Description
Given an integer array nums, rotate the array to the right by k steps, where k is non-negative.
Example 1:
Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
rotate 1 steps to the right: [7,1,2,3,4,5,6]
rotate 2 steps to the right: [6,7,1,2,3,4,5]
rotate 3 steps to the right: [5,6,7,1,2,3,4]
Example 2:
Input: nums = [-1,-100,3,99], k = 2
Output: [3,99,-1,-100]
Explanation:
rotate 1 steps to the right: [99,-1,-100,3]
rotate 2 steps to the right: [3,99,-1,-100]
Constraints:
1 <= nums.length <= 10^5
-2^31 <= nums[i] <= 2^31 - 1
0 <= k <= 10^5
Follow up:
Try to come up with as many solutions as you can. There are at least three different ways to solve this problem.
Could you do it in-place with O(1) extra space?
Solution
Solved after help...
For a space o ( 1 ) o(1) o(1) solution, one straightforward way is: start with 0
, use current value to set the new index, and then update the current value with the original value in the new index, and keep going until we replaced all the numbers.
This works for most cases, but doesn't work when k = k % n
, for example, when n=4
and k=2
, if we start with 0
, then we jump to 2
, then we jump back to 0
. This could create a loop.
To avoid this loop, before starting, we should keep track of where we started, and once we found we arrived at start again, we increase start by 1 and keep going.
Time complexity: o ( n ) o(n) o(n)
Space complexity: o ( 1 ) o(1) o(1)
Code
python3
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
k %= len(nums)
rotate_cnt = 0
start = 0
while rotate_cnt < len(nums):
new_index, value_to_set = start, nums[start]
while True:
new_index = (new_index + k) % len(nums)
ori_value = nums[new_index]
nums[new_index] = value_to_set
value_to_set = ori_value
rotate_cnt += 1
if new_index == start:
break
start += 1