题目
给定一个数组,将数组中的元素向右移动 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) 的 原地 算法。
代码思路
方法一:(最开始的思路,但是超时了)
设置两个循环,内循环为旋转一次,外循环用k来决定要循环多少次旋转
使用临时变量temp存储数组最后一个数的值,再将倒数第二个数的值覆盖倒数第一个数,再将倒数第三个数的值覆盖倒数第二个数的值。。。以此类推,最后将temp的值赋给第一个数,即完成一次旋转操作,再用外循环决定执行几次旋转操作。。
class Solution {
public:
void rotate(vector<int>& nums, int k) {
if (nums.size() != 0 or nums.size() != 1){
int i,temp,j;
for (j = k%nums.size();j>0;j--){
temp = nums[nums.size()-1];
for(i = nums.size()-1;i>0;i--){
nums[i] = nums[i-1];
}
nums[0] = temp;
}
}
}
};
方法二:
(最简便的方法)
rotate(容器头部,新的头部,容器尾部)
旋转函数,作用同题目类似
例如:容器a [1,2,3,4,5]
std::rotate(std::begin(a),std::begin(a)+2,std::end(a))
第一个参数为1,第二个参数为3,第三个参数为5
代码运行后为 a=[3,4,5,1,2]
即3成为新的头部
class Solution {
public:
void rotate(vector<int>& nums, int k) {
if (nums.size() != 0 or nums.size() != 1){
std::rotate (std::begin(nums),
std::begin(nums)+nums.size()k%nums.size(),std::end(nums));
}
}
};
方法三:
使用反转函数reverse()
reverse函数用于反转在[first,last)范围内的顺序(包括first指向的元素,不包括last指向的元素),reverse函数没有返回值。1
如果是用reverse(容器名.begin,容器名.end)
a=[1,2,3,4,5]
变成 a=[5,4,3,2,1]
猜测是因为end指向最后一个元素的末尾(空)
实现思路为:
旋转可以通过三次反转实现
反转整个部分
反转左部分
反转右部分
左部分和右部分的边界为原先容器第一个元素旋转后到达的位置
例: 原 1,2,3,4,5 k=3(边界为原4的位置)
反整:5,4,3,2,1
反左:3,4,5,2,1
反右:3,4,5,1,2
class Solution {
public:
void rotate(vector<int>& nums, int k) {
if (nums.size() != 0 or nums.size() != 1){
reverse(nums.begin(),nums.end());
reverse(nums.begin(),
nums.begin()+k%nums.size());
reverse(nums.begin()+k%nums.size(),nums.end());
}
}
};
引用:
https://cloud.tencent.com/developer/article/1150743
反转函数的说明引用于上面文章 ↩︎