189. Rotate Array
Given an array, rotate the array to the right by k steps, where k is non-negative.
Example 1:
Input: [1,2,3,4,5,6,7] and 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: [-1,-100,3,99] and 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]
Note:
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?
grandyang: http://www.cnblogs.com/grandyang/p/4298711.html
方法1:
思路:
copy一份nums,填进去。注意comment掉的地方被省略成了一句话。rotate的本质是对n取余。
Complexity
Time complexity : O(n)
Space complexity: O(n)
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
vector<int> copy(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++){
// int idx = i + k;
// if (idx < n ){
// nums[idx] = copy[i];
// }
// else {
// nums[idx - n] = copy[i];
// }
nums[(i + k) % n] = copy[i];
}
return ;
}
};
方法2:
一次变一个数,用一个临时变量来记录被取代的那个位置。
Complexity
Time complexity: O(n)
Space complexity: O(1)
易错点
要注意排除死循环或者overflow的case:
- 如果i回到了start, 有可能会出现一直跳不出某几个数的情况,比如n是偶数的时候。这个时候要手动shift start and i,以便继续推进loop。
if (nums.empty() || (k %= nums.size()) == 0) return;
这个特判条件容易漏掉,如果k = 0 或者刚好整除n,是不可以进入循环的。除非在循环里加一个boundary,不然每次都跳回同样的位置,start和i 不断++,最终会overflow
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
if (nums.empty() || (k %= nums.size()) == 0) return;
int i = 0;
int cur = nums[i];
int cnt = 0;
int start = i;
while (cnt++ < n){
i = (i + k) % n;
int tmp = nums[i];
nums[i] = cur;
if (start == i){
start ++;
i = start;
cur = nums[i];
}
else{
cur = tmp;
}
}
}
};
方法3: 反转字符
class Solution {
public:
void rotate(vector<int>& nums, int k) {
if (nums.empty() || (k %= nums.size()) == 0) return;
int n = nums.size();
reverse(nums.begin(), nums.begin() + n - k);
reverse(nums.begin() + n - k, nums.end());
reverse(nums.begin(), nums.end());
}
};
方法4: STL
思路:
通过 stl push_back, erase的api
Complexity
Time complexity: ? 取决于vector是怎么实现的
class Solution {
public:
void rotate(vector<int>& nums, int k) {
if (nums.empty() || (k %= nums.size()) == 0) return;
int n = nums.size();
for (int i = 0; i < n - k; ++i) {
nums.push_back(nums[0]);
nums.erase(nums.begin());
}
}
};