Given an array, rotate the array to the right by k steps, where k is non-negative.
Follow up:
- Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
- Could you do it in-place with O(1) extra space?
Solutions:
https://leetcode.com/problems/rotate-array/solution/
k = k % nums.length
(1) Brute force: rotate
(2) Using extra space
(3) Cyclic replacement
Time O(n); Space O(1)
Replace each element in the array by replacing next[(current+k)%n] with current while current!=start
for example, replace 3 with 1, 5 with 3, 1 with 5(start = current); then, start++, replace 4 with 2, 6 with 4, 2 with 6; count=n, end.
Java:
class Solution {
public void rotate(int[] nums, int k) {
k = k % nums.length;
int count = 0;
for (int start = 0; count < nums.length; start++) {
int current = start;
int prev = nums[start];
do {
int next = (current + k) % nums.length;
int temp = nums[next];
nums[next] = prev;
prev = temp;
current = next;
count++;
} while (start != current);
}
}
}
Python:
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
n = len(nums)
k %= n
start = count = 0
while count < n:
current, prev = start, nums[start]
while True:
next_idx = (current + k) % n
nums[next_idx], prev = prev, nums[next_idx]
current = next_idx
count += 1
if start == current:
break
start += 1
(4) Reverse:
based on the fact that when we rotate the array k times, kk elements from the back end of the array come to the front and the rest of the elements from the front shift backwards
For the reverse function, swap the two ends of the array.
Java:
class Solution {
public void rotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
}
Python:
class Solution:
def reverse(self, nums: list, start: int, end: int) -> None:
while start < end:
nums[start], nums[end] = nums[end], nums[start]
start, end = start + 1, end - 1
def rotate(self, nums: List[int], k: int) -> None:
n = len(nums)
k %= n
self.reverse(nums, 0, n - 1)
self.reverse(nums, 0, k - 1)
self.reverse(nums, k, n - 1)