题目描述:
给定一个数组,将数组中的元素向右移动 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) 的 原地 算法。
方法1:
主要思路:
(1)直接连续反转三次数组即可实现右旋的数组;
class Solution {
public:
void rotate(vector<int>& nums, int k) {
k%=nums.size();
reverse(nums.begin(),nums.begin()+nums.size()-k);//反转前面部分
reverse(nums.begin()+nums.size()-k,nums.end());//反转后面部分
reverse(nums.begin(),nums.end());//反转整体
return ;
}
};
方法2:
主要思路:
(1)使用额外的数组存储后面的需要反转的部分,然后将前面的部分移动得到后面,再把保存的后面的部分加到数组的前面即可;
class Solution {
public:
void rotate(vector<int>& nums, int k) {
k%=nums.size();
vector<int> tmp(k,0);
for(int i=0;i<k;++i){//保存后面的部分
tmp[i]=nums[nums.size()-k+i];
}
for(int i=nums.size()-k-1;i>=0;--i){//将前面的部分移动到后面
nums[i+k]=nums[i];
}
for(int i=0;i<k;++i){//将后面的部分放到前面
nums[i]=tmp[i];
}
return ;
}
};