Rotate Array
Rotate an array of n elements to the right by k steps.
For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7]
is rotated to [5,6,7,1,2,3,4]
.
#1. Make an extra copy and then rotate. 最普通的解法
Time complexity: O(n). Space complexity: O(n).
class Solution
{
public:
void rotate(int nums[], int n, int k)
{
if ((n == 0) || (k <= 0))
{
return;
}
// Make a copy of nums
vector<int> numsCopy(n);
for (int i = 0; i < n; i++)
{
numsCopy[i] = nums[i];
}
// Rotate the elements.
for (int i = 0; i < n; i++)
{
nums[(i + k)%n] = numsCopy[i];
}
}
};
#2. Start from one element and keep rotating until we have rotated n different elements. 每个元素只要移动了就一定到了自己的该在位置,所以移动n-1次(n个)元素。
Time complexity: O(n). Space complexity: O(1).
class Solution
{
public:
void rotate(int nums[], int n, int k)
{
if ((n == 0) || (k <= 0))
{
return;
}
int cntRotated = 0;
int start = 0;
int curr = 0;
int numToBeRotated = nums[0];
int tmp = 0;
// Keep rotating the elements until we have rotated n
// different elements.
while (cntRotated < n)
{
do
{
tmp = nums[(curr + k)%n];
nums[(curr+k)%n] = numToBeRotated;
numToBeRotated = tmp;
curr = (curr + k)%n;
cntRotated++;
} while (curr != start);
// Stop rotating the elements when we finish one cycle,
// i.e., we return to start.
// Move to next element to start a new cycle.
start++;
curr = start;
numToBeRotated = nums[curr];
}
}
};
倒序版:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
k = k%n;
int rotateCnt = 0;
int start = n - 1;
while(rotateCnt < n){
int tmp = nums[start];
int ptr = start;
do{
nums[ptr] = nums[(ptr-k+n)%n];
ptr = (ptr-k+n)%n;
rotateCnt++;
}while(ptr!=start);
nums[(ptr+k)%n] = tmp;
start--;
}
}
#3. Reverse the first n - k elements, the last k elements, and then all the n elements. 每部分翻转两次恰好是结果。
Time complexity: O(n). Space complexity: O(1).
class Solution
{
public:
void rotate(int nums[], int n, int k)
{
k = k%n;
// Reverse the first n - k numbers.
// Index i (0 <= i < n - k) becomes n - k - i.
reverse(nums, nums + n - k);
// Reverse tha last k numbers.
// Index n - k + i (0 <= i < k) becomes n - i.
reverse(nums + n - k, nums + n);
// Reverse all the numbers.
// Index i (0 <= i < n - k) becomes n - (n - k - i) = i + k.
// Index n - k + i (0 <= i < k) becomes n - (n - i) = i.
reverse(nums, nums + n);
}
};