本题有多种解法,但是找到简单的解法其实并不是很简单,额,我自己就花了不少时间。。。。以下有三种解法:
解法一,考虑每k个位置的数互换顺序,可得到如下解法。
void rotate(vector<int>& nums, int k) {
if(nums.empty()||k==0) return;
int n = nums.size();
k %= n;
if(k==0) return;
vector<bool> flag(n,false);
for(int i=0;i<k;++i)
{
if(flag[i]==true) continue;
int tmp = nums[i];
int j = i+k;
while(flag[j]!=true)
{
int ttmp = nums[j];
nums[j] = tmp;
tmp = ttmp;
flag[j] = true;
j += k;
j %= n;
}
}
}
时间复杂度为O(n).
解法2:
考虑右移后的序列和右移之前的序列关系,可以注意到最后的k个元素右移后彼此的相对位置不变,但是在整个数组中转换到数组首;而前n-k个元素位置移到最后,并且彼此位置不变。如果将原数组对折交换元素,那么前n-k个元素到后面n-k个位置上,而后k个元素换到前k个位置上了,但是,两部分内的元素位置的相对位置与右移后的相对位置正好倒过来了。所以先将两部分的元素倒过来,再对折。
void Myroute(vector<int> &nums,int s,int e)
{
int mediu = (s+e+1)/2-1;
int p=mediu,q=e-(p-s);
while(p>=s)
{
int tmp = nums[q];
nums[q]=nums[p];
nums[p]=tmp;
++q;
--p;
}
}
public:
void rotate(vector<int>& nums, int k) {
if(nums.empty()||k==0) return;
int n = nums.size();
k %= n;
if(k==0) return;
Myroute(nums,0,n-k-1);
Myroute(nums,n-k,n-1);
Myroute(nums,0,n-1);
}
解法三:
右移k个位置,实际上可以看做将前n-k个元素先砍掉,然后放在后面,也可以将后k个位置砍掉放在前面。
void rotate(vector<int>& nums, int k) {
int len=nums.size();
if(len==1) return;
k=k%len;
k=len-k;
int tem;
for(int i=0;i<k;i++){
tem=nums[0];
nums.erase(nums.begin());
nums.push_back(tem);
}
}