标签:different ble esc 引入 reverse ++i void 方法 solution
LeetCode 189
Rotate an array of n elements to the right by k steps.
For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7]
is rotated to [5,6,7,1,2,3,4]
.
Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
https://leetcode.com/problems/rotate-array/description/
方法一:借助额外空间
借助额外空间来移动数组很简单,这种方法就不说了。
方法二:额外空间为0,只依靠交换
交换的最终目的是将位置为 i 的数字移动到 (i+k)%nums.size() 的位置,假设数组是1234567时,k = 3,则
1234567
5671234,
我们从0位置开始操作,将nums[0] 移动到 0+k 的位置,原来在0+k 位置的数字 num[0+k] 此时需要移动到下一个位置,也就是num[(0+k+k)%nums.size()]的位置,问题来了,如何做到这样的移动。
我们引入三个变量来解释这个过程
storeposition——在交换之后用来存储位置被占的那个数字,也就是上述中的num[0+k]
currentposition——当前要移动的数字在数组中的初始位置
nextposition——当前要移动的数字的目的位置,同时也是下一个要移动的数字的位置
初始时storeposition= 0,currentposition = 0,nextposition = 0,k = 3
对照代码有以下过程:
storeposition currentposition nextposition i
1 2 3 4 5 6 7 0 0 3 0
4 2 3 1 5 6 7 0 3 6 1
7 2 3 1 5 6 4 0 6 2 2
3 2 7 1 5 6 4 0 2 5 3
6 2 7 1 5 3 4 0 5 1 4
2 6 7 1 5 3 4 0 1 4 5
5 6 7 1 2 3 4 0 4 0 6
若k可以被nums.size()整除,则k和nums.siz()的最小公倍数就是nums.size()本身,则当storeposition = nextposition时,只移动了整个过程的k/nums.size(),如k=2,nums= 123456,则第一圈移动完只移动了2/6,即整个过程的1/3.
再举一个例子
s c n i
1 2 3 4 5 6 0 0 2 0
3 2 1 4 5 6 0 2 4 1
5 2 1 4 3 6 0 4 0 2 //此时s = n = 0,说明位置为0,2,4的数字都已经到达了自身的最终位置,而n继续+k的话,并不会移动其他元素,因此此时需要将s+1,换一个“圈”
5 2 1 4 3 6 1 4 3 3 //s+=1,n=s+k, i++
5 4 1 2 3 6 1 3 5 4
5 6 1 2 3 4 1 5 1 5
1 void swap(int * a, int * b) 2 { 3 *a = *a ^ *b; 4 *b = *a ^ *b; 5 *a = *a ^ *b; 6 } 7 void rotate(vector<int>& nums, int k) { 8 if (nums.size() < 2 || k%nums.size() == 0) return; 9 k = k % nums.size(); 10 int storeposition = 0,nextposition = k; // 11 for (unsigned i = 0; i < nums.size(); ++i) 12 { 13 swap(&nums[storeposition], &nums[nextposition]); 14 nextposition = (nextposition + k) % nums.size(); 15 if (nextposition == storeposition) 16 { 17 ++i; 18 ++storeposition; 19 nextposition = (storeposition + k)%nums.size(); 20 } 21 } 22 }
方法三:分解过程
1234567 -->5671234的过程可以分解成以下过程:
1234567-->7654321-->5674321-->5671234
即反转三次,代码如下:
1 void rotate(vector<int>& nums, int k) 2 { 3 k = k % nums.size(); 4 if (nums.size() < 2 || k == 0) return; 5 vector<int>::iterator it = nums.begin(); 6 for (int i = 0; i < k; ++i) ++it; 7 reverse(nums.begin(),nums.end()); 8 reverse(nums.begin(),it); 9 reverse(it++,nums.end()); 10 }
标签:different ble esc 引入 reverse ++i void 方法 solution
原文地址:http://www.cnblogs.com/qmdt/p/7460672.html