Original question: https://leetcode.com/problems/rotate-array/description/
Answer:
Solution 1): time O(n), space O(n)
Solution 2): time O(n), space O(1) - The underlying truth of rotation is actually
reversing.
Solution 3): time O(n*k), space O(1)
Solution 4): time O(n), space O(1)- Basic logic of it is to move "smaller part" in the expected result first, then modify the remaining part, i.e. "bigger part" using same logic.
public class Solution {
public void rotate(int[] nums, int k) {
k = k % nums.length;
//(1) new array;
int[] oldNums = nums.clone();
for(int i = 0; i< nums.length;i++){
nums[(i+k)%nums.length] = oldNums[i];
}
//(2) reverse 3 times
// reverse(nums, 0, nums.length-1);
// reverse(nums, 0, k-1);
// reverse(nums, k, nums.length-1);
//(3) move k times
// while(k-->0){
// int tmp = nums[nums.length-1];
// for(int i = nums.length-1; i>0; i--){
// nums[i] = nums[i-1];
// }
// nums[0] = tmp;
// }
}
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--;
}
}
}
Solution 4)
public class Solution {
public void rotate(int[] nums, int k) {
if (nums == null || k <= 0) {
return;
}
helper(nums, 0, nums.length - 1, k % nums.length);
}
private void helper(int[] nums, int left, int right, int k) {
if ( k <= 0 || left >= right) {
return;
}
int steps = right - left + 1 - k;
int temp;
if (steps > k) {
for (int i = 0; i < k; i ++) {
temp = nums[i + left];
nums[i + left] = nums[left + steps + i];
nums[left + steps + i] = temp;
}
helper(nums, left + k, right, k);
} else {
if (steps < k) {
for (int i = 0; i < steps; i ++) {
temp = nums[right - i];
nums[right - i] = nums[right - k - i];
nums[right - k - i] = temp;
}
helper(nums, left, right - steps, k - steps);
} else {
for (int i = 0; i < steps ; i ++) {
temp = nums[i + left];
nums[i + left] = nums[left + k + i];
nums[left + k + i] = temp;
}
return;
}
}
}
}