数组是最简单的一种数据结构。我们经常碰到的一个基本问题,就是寻找整个数组中最大的数,或者最小的数。这时,我们都会扫描一遍数组,把最大(最小)的数找出来。如果我们需要同时找出最大和最小的数呢?
对于一个由N个整数组成的数组,需要比较多少次才能把最大和最小的数找出来呢?
分析与解法
解法一:分别求最大和最小值
可以分别求出数组的最大值和最小值,这样,我们需要比较2N次才能求解。
解法二:分组求解
(1) 按顺序将数组中相邻的两个数分在同一组;
(2) 比较同一组的两个数,将大的数放在偶数位上,小的放在奇数位上;
(3) 最后,从偶数位上求最大值,奇数位上求最小值即可。
一共需要比较1.5N次。这种办法虽然比较次数变少了,但却破坏了原数组。
解法三:改进的分组
(1) 用两个变量max和min分别存储当前的最大值和最小值。
(2) 同一组的两个数比较完之后,不再调整顺序,将其中较大的与当前max比较,较小的与min比较;
(3) 如此反复,直到遍历完整个数组。
整个过程比较次数为1.5N次。
解法四:分治策略
分别求出前后N/2个数的min和max,然后,取较小的min,较大的max即可。
需要比较的次数为1.5N-2,分析略。
扩展问题
如果需要找出N个数中的第二大数,需要比较多少次呢?是否可以使用类似的分治思想来降低比较的次数呢?
思路一:
用两个变量分别存最大值max和次大值ans,遍历数组:
如果arr[i] > max,则更新max=arr[i],ans=max;
否则如果arr[i] > ans,则更新ans=arr[i];
否则,不进行更新操作。
这个方法最多的比较次数为2*N次,最小N次。
思路二:快速选择算法
寻找第k大的整数问题的一个特例,比较次数的分析似乎有点困难。