旋转数组
给定一个数组,将数组中的元素向右移动 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) 的原地算法。
旋转数组
数组法:error: Line 23: index 11938 out of bounds for type 'int [100]'
//法1:少量数组法//法1:少量数组交换法
//法1:少量数组法 void rotate(int* nums, int numsSize, int k) { int i=0; int temp[100];//临时存放 k = k % numsSize; //右移最小次数 /* int rotate_dir = 1;//右移标志 if(k>numsSize/2) rotate_dir = 0;//左移 if(!rotate_dir) //左移 { return ; } */ //默认右移 //(0 ~ num-1-k) --> (k ~ num-1) // for(i=numsSize-1;i>numsSize-1-k;i--) //没有等于号 i>=numsSize-1-k temp[i+k-numsSize] = nums[i]; //保存被覆盖的数nums[i] for(i=numsSize-1; i>=k; i--) nums[i] = nums[i-k]; //nums[i]被覆盖,提前保存到temp中去, 再nums[i]=移位前一个数 for(i = 0; i<=k-1; i++) //赋值 nums[i]=temp[i]; }
//法2:全部数组法
void rotate(int* nums, int numsSize, int k) { int i=0; int temp[100];//临时存放 k = k % numsSize; //右移最小次数 for(i=0;i<numsSize;i++) temp[(i+k)%numsSize] = nums[i];//创造一个一样大小的数组,全部赋值到temp中 for(i=0;i<numsSize;i++) nums[i] = temp[i]; //再把temp复制给nums }
//法3:只保留一个变量,逐个跳动法
void rotate(int* nums, int numsSize, int k) { int now = 0,start = 0, data_to_next = 0, temp = 0; int cnt = numsSize ;//用来表示跳转次数,次数到了,就停止循环 k = k%numsSize; if(k==0) return; for(start = 0;start<numsSize;start++) { now = start; data_to_next = nums[start%numsSize]; //第一个数,先提出来,用于 与下一个数交换 while(1) { now = now+k; temp = nums[now%numsSize]; //交换一次 nums[now%numsSize] = data_to_next; data_to_next = temp; cnt--; if((now%numsSize) == start) //如果交换到start的开始,就结束本次跳转交换 break; } if(cnt==0) break; } }
//法4:交换位置 逆序法
实现起来最简单!!!
Original List : 1 2 3 4 5 6 7 After reversing all numbers : 7 6 5 4 3 2 1 After reversing first k numbers : 5 6 7 4 3 2 1 After revering last n-k numbers : 5 6 7 1 2 3 4 --> Result
//法4:调换位置,3次逆序法 void reverse(int *buf, int start, int end) { int i=0; int temp=0; int cnt; cnt = (int)((end-start)/2+0.5); for(i=0;i<=cnt;i++) { temp = buf[start+i]; buf[start+i] = buf[end-i]; buf[end-i] = temp; } } void rotate(int* nums, int numsSize, int k) { /* //测试reverse函数可以工作 int i = 0; reverse(nums,0,numsSize-1); for(i = 0;i<numsSize;i++) printf("%d ",nums[i]); */ k = k%numsSize; if(k == 0 ) return; reverse(nums,0,numsSize-1); reverse(nums,0,k-1); reverse(nums,k,numsSize-1); }