要右移k次,且只能用O(1)的空间,最简单的办法是循环k次,每次用一个变量temp记录最后一个位置的值,然后让最后一个下标(下标从0开始)到下标1的值都为前一个元素的值,再让下标0的值为temp。
这样进行k次之后,就完成了循环右移k次。
不过这样会超时,一个较简单的做法是,对于右移到数组前边的k个数,将他们看作一个部分,然后在这k个数之前的所有数看作一部分,两部分分别做翻转(reverse操作),然后再把整个数组做翻转,得到的就是右移k次之后的数组。 貌似库函数rotate也是这么实现的。
举个例子吧,第一个样例[1,2,3,4,5,6,7],k = 3,总共要右移三次,最后得到的数组是[5,6,7,1,2,3,4]。
我们把数组右移到前面部分和后面部分的数组划分为两个部分,分别做reverse: 前四个元素reverse得到:[4, 3, 2, 1], 后三个元素reverse得到:[7, 6, 5]。
这两部分都reverse之后的数组就是[4, 3, 2, 1, 7, 6, 5], 然后我们把整个数组reverse一下:[5, 6, 7, 1, 2, 3, 4]。就ok了。
这里要注意,k可能比数组长度还大,但是每右移数组的长度次,就等于回到了原点,所以在reverse操作之前需要把k对数组的长度取余。
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int size = nums.size();
k %= size;
reverse(nums.begin(), nums.end() - k);
reverse(nums.end() - k, nums.end());
reverse(nums.begin(), nums.end());
}
};