rotate的几种实现
问题描述
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].
方法一
每次向左移动一步,移动k次即可,时间复杂度为O(nk)
void rotate(int nums[], int n, int k) {
int i, j, tmp;
for (i = 0; i < k; i++) {
tmp = nums[n - 1];
for (j = n - 1; j > 0; j--) {
nums[j] = nums[j - 1];
}
nums[0] = tmp;
}
}
方法二
问题可以描述为,将AB转换为BA,由公式 (ArBr)r = BA可以很方便的实现,时间复杂度为O(n)
void rotate(int nums[], int n, int k) {
k %= n;
reverse(nums, 0, n - k);
reverse(nums, n - k, n);
reverse(nums, 0, n);
}
方法三
序列为AB
如果len(A) < len(B),则可以将AB表示为 AB1B2 ,其中len(A) == len( B1 )。将A和 B1 互换后则序列为 B1AB2 ,这个时候 B1 已经在转换后的位置,剩下的只需要处理 AB2 序列即可。
如果len(A) > len(B),则可以将AB表示为 A1A2B ,其中len( A1 ) == len(B)。将 A1 和B互换后则序列为 BA2A1 ,这个时候B已经在转换后的位置,剩下的只需要处理 A2A1 序列即可。
由上可知,每次循环都可以完成k个元素的转换,则只需要遍历一遍序列就可以完成转换。在每次循环之后,n需要减去k,k因为必须小于n,所以k要对n
取余。当k等于0的时候则转换完成。
时间复杂度为O(n)
void rotate(int nums[], int n, int k) {
for (; k %= n; n -= k)
for (int i = 0; i < k; i++)
swap(*nums++, nums[n - k]);
}
Reference
- Rotate Array
- 编程珠玑
- STL源码剖析