leetcode 189. 旋转数组(Rotate Array)
题目描述:
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]
示例 2:
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
说明:
- 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
- 要求使用空间复杂度为 O(1) 的原地算法。
算法:
class Solution {
public:
void rotate1(vector<int>& nums, int k){
// method 1
int sz = nums.size();
if(k <= sz/2){
for(int i = 0; i < k; i++){
// for the i-th step
int pre = nums[sz-1];
for(int j = sz - 1; j > 0; j--){
nums[j] = nums[j-1];
}
nums[0] = pre;
}
}else{
k = sz - k;
for(int i = 0; i < k; i++){
// for the i-th step
int pre = nums[0];
for(int j = 0; j < sz - 1; j++){
nums[j] = nums[j+1];
}
nums[sz - 1] = pre;
}
}
}
int gcd(int a, int b){
int c = a;
while(a % b){
c = a % b;
a = b;
b = c;
}
return b;
}
void rotate2(vector<int>& nums, int k){
// method 2
int sz = nums.size();
int cycle = gcd(sz, k);
int _sz = sz / cycle;
for(int i = 0; i < cycle; i++){
int val = nums[i];
int idx = i;
int pre = 0;
for(int j = 0; j < _sz-1; j++){
pre = (idx + sz - k)%sz;
nums[idx] = nums[pre];
idx = pre;
}
nums[idx] = val;
}
}
void flip(vector<int>& nums, int start, int end){
while(start < end){
swap(nums[start++], nums[end--]);
}
}
void rotate3(vector<int>& nums, int k){
// method 3
// target: move the last k elements to the front
// 1. flip the whole vector
// 2. flip the first k elements
// 3. flip the rest of elements
int sz = nums.size();
flip(nums, 0, sz-1);
flip(nums, 0, k-1);
flip(nums, k, sz-1);
}
void rotate(vector<int>& nums, int k) {
int sz = nums.size();
if(sz <= 1){
return ;
}else{
k %= sz;
}
if(k == 0){
return ;
}
// rotate1(nums, k); // time limited
rotate2(nums, k); // accept
// rotate3(nums, k); // accept
}
};

浙公网安备 33010602011771号