方法1:暴力解法
每次向右旋转一个元素,用tem储存最后一个元素,最后赋值给下标为0的位置,重复k次即可。
时间复杂度O(n^2)
空间复杂度O(1)
void rotate(int* nums, int numsSize, int k){ //重复k次 while(k--) { //保存最后一个元素的值 int tem = nums[numsSize-1]; //将前numsSize-1个元素向后移一位 for(int i =numsSize - 1;i>0;i--) { nums[i] = nums[i-1]; } //把最后的元素赋给第一个位置 nums[0]=tem; } return nums; }
此代码会运行超时
方法2 :借助一个新数组
算法思想:声明一个新数组arr[],nums = [1,2,3,4,5,6,7], k = 3,输出[5,6,7,1,2,3,4],其实就是在nums[numsSize-1]的位置开始循环赋值,直到下标为numsSize-2时结束.
时间复杂度O(n)
空间复杂度O(n)
void rotate(int* nums, int numsSize, int k){ //申请一个新数组 int* arr =(int *)malloc(sizeof(int)*(numsSize)); //起始下标 int index =numsSize-k%numsSize; int i = 0; //i指向新数组下标,新数组满了,即为旋转完成 for(i = 0;i<numsSize;i++) { arr[i] = nums[(index%numsSize)]; index++; } //还要必须返回原来的数组 for(i = 0;i<numsSize;i++) { nums[i]=arr[i]; } return nums; }
方法3:技巧
假如有[1,2,3,4,5,6,7]这样一个数组 k = 3
先将前numsSize-k个元素逆置[4,3,2,1,5,6,7]
再将后k个元素逆置[4,3,2,1,7,6,5]
最后将整体逆置[5,6,7,1,2,3,4]
时间复杂度O(n)
空间复杂度O(n)
此方法面试常考,需要熟悉
//逆置区间为left-right的元素 void reverse(int *nums,int left,int right) { while(left<right) { int tem =nums[right]; nums[right] = nums[left]; nums[left] = tem; left++; right--; } } void rotate(int* nums, int numsSize, int k){ k = k%numsSize; reverse(nums,0,numsSize-k-1); reverse(nums,numsSize-k,numsSize-1); reverse(nums,0,numsSize-1); return nums; }
以上为轮转数组的题解,如有问题,欢迎在评论区讨论💞