《算法导论》选择问题(找第K大的数)

选择问题(Selection Problem),即在n个元素的集合中寻找第K小的元素的问题。第K小的元素又叫第K个顺序统计量。有以下几种变体:
- 找最大值和最小值;同时找最大和最小值
- 找中位数(第n/2小)
- 找任意第K小的元素
- 找Top-K的元素

找最大值和最小值

要确定最大值或者最小值,在n个元素中进行n-1次比较是必须的,也是最优方法。

要同时确定最大值和最小值,如果独立寻找,各用n-1次比较,共用2n-2次比较,但这不是最优方法。

事实上,最多需要3n/2次比较就可以同时找到最大最小值:

  1. 成对处理元素,两两成对比较大小,得到较大的元素和较小元素(1次比较)
  2. 较大元素和当前最大值比较,较小元素和当前最小值比较(2次比较)
  3. 处理n/2对元素共需要3n/2次比较

当n为奇数,把第一个元素设为最大值和最小值,剩下的两两成对,共做3n/2次比较;当n为偶数,先做一次初始比较,然后做剩下的3(n-2)/2次比较,共3n/2-2次比较。因此最多做3n/2次比较。


选择算法(线性时间)

类似于快排的划分函数,用分治法实现最坏情况线性时间O(n)的选择算法。

选择算法Select(S, k):
1. 将n个元素划分为n/5组,每组5个元素,最多有一个组由剩下的n mod 5个元素组成
2. 寻找ceil(n/5)个组中每一组的中位数:对每组5个元素进行插入排序,排序后选择中位数
3. 从2中找出的ceil(n/5)个中位数,递归调用Select()找出其中位数x
4. 用划分函数将输入元素按x进行划分,比x小的构成S1,比x大的构成S2
5. 如果|S1|=k-1,则返回x为所求(第k小)
6. 否则如果|S1|>k,则在S1调用Select(S1, k);否则在S2调用Select(S2, k-|S1|-1)

用迭代法可以证明这个Select算法将时间复杂度降到限行时间O(n)

Reference

  • 《算法导论(第二版)》第9章

你可能感兴趣的:(算法笔记)