(Banner图片来自一喜欢摄影的同学:心碎乌托邦)
问题
Rotate a one-dimensional vector of n elements left by i positions.
For instance, with n = 8 and i = 3, the vector abcdefg
is rotated to deftabc
.
Naive idea
- 另外声明一个数组存储前i个元素,然后把后面的元素左移i位,最后再把数组里面 的i个元素复制到原数组的最右边的i个位置。显然这种方法是空间复杂度是O(i),时间 复杂度O(n).
- 另
t=x[0]
,然后movex[i]
tox[0]
,x[2i]
tox[i]
,依次类推,然后再 把t
放到最后的位置;然后是x[1]
,最后一直到x[i-1]
。空间复杂度O(1),时间 复杂度O(n).Aha!
首先,show the code:
1
2
3reverse(0, i-1); /* cbadefgh */
reverse(i, n-1); /* cbahgfed */
reverse(0, n-1); /* defghcba */
这算法的过程的有点神奇,过程比较清楚,分为三步:
- 反转前i个元素;
- 反转后面n-i个元素;
- 反转所有的n个元素。
虽然结果正确,但难免没有说服力,先面就证明一下。
- 对于
0 <= x < i
的元素,第一步反转以后,x
的位置为x'
, 因为x'
和x
关于i/2
对称,所以x' = i-x
- 对于
0 <= y < i
的元素,第二步反转以后,y
的位置为y'
, 因为y'
和y
关于(n-1+i)/2
对称,所以y' = n-1+i-y
- 对于
x
,平移以后最终的位置是x => n-1+x-i
。 第三步反转后,x'
的位置为:x' => n-1 - x' = n-1+x-i
- 对于
y
,平移以后最终的位置是y => y-i
。 第三步反转后,y'
的位置为:y' => n-1 - y' = y-i
证明结束。
同时可以引出一个公式: 该公式推广: