36. 逆转数组(一)

一. 问题

给定一个数组 A,描述一个将 A 逆转的高效算法。例如,如果 A = (1, 2, 3, 4, 5),逆转以后是 A = (5, 4, 3, 2, 1)。除了 A 本身使用的空间外,只能使用 O( 1 )的额外内存。算法的运行时间是多少?

二. 思路

规定只能使用固定大小的额外内存,说明需要用到元素交换,这将会改变原序列。(如果可以使用更多的内存,那么可以重新申请一个和原序列大小相同的新序列,然后将原序列元素从后往前,依次放入新序列中)。

三. 代码实现

1 void reverse_array(vector<int>& data) {
2     int temp;
3     for (int i = 0, j = data.size() - 1; i < j; ++i, --j) {
4         temp = data[i];
5         data[i] = data[j];
6         data[j] = temp;
7     }
8 }

算法正确性证明:

用到两个变量 i 和 j ,i 赋值为序列开始下标,j 赋值为序列结束下标。

现在需要分两种情况:

(1)当序列元素为偶数时,i 和 j 会在若干步以后,前后紧挨着,在执行完这一步以后, i 的值会大于 j ,说明序列元素全部逆转。

(2)当序列元素为奇数时, i 和 j 会在若干步以后相遇(都指向最中间的元素),而这个中间元素不需要与别人交换,或者说,它跟它自己进行交换,交换完成后,还是会出现 i 大于 j 的情况,说明整个序列逆转完成。显然,自己和自己交换这一步骤是多余的。

于是我们可以证明,该算法正确,并且时间复杂度是 O(n),因为遍历一遍序列即可完成任务。

posted @ 2020-08-24 22:05  Hello_Nolan  阅读(233)  评论(0编辑  收藏  举报