题目
给定一个整数数组 nums
,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
思路
也就是将元素[i]移动到[i+k]的位置。本质上是将数组[0:k-1]
赋值nums[size-k:size-1]
,[k:size-1]
赋值nums[0:size-k-1]
。
有几种可能的思路
-
整个数组倒序,前k个再倒序,后size-k个再倒序。
class Solution { public: void rotate(vector<int>& nums, int k) { k=k%nums.size(); reverse(nums.begin(),nums.end()); reverse(nums.begin(),nums.begin()+k); reverse(nums.begin()+k,nums.end()); } };
-
暴力交换。i移动到(i+k)%size,(i+k)%size移动到(i+2k)%size,直到(i+m*k)%size=i。每次循环遍历到的元素数a应该满足a*k=b*size。为取到最小的b,a应该是k,size的最小公倍数/k,因此迭代次数num应该为k,size的最大公约数。
代码:
class Solution { public: int gcd(int a, int b) { while(b != 0) { int c = a % b; a = b; b = c; } return a; } void rotate(vector<int>& nums, int k) { k=k%nums.size(); int tims=gcd(nums.size(),k); for(int i=0;i<tims;i++) { int l=i; int r=(i+k)%nums.size(); int temp=nums[l]; while(r!=i) { nums[r]=temp+nums[r]; temp=nums[r]-temp; nums[r]=nums[r]-temp; l=r; r=(l+k)%nums.size(); } nums[r]=temp; } } };