斯坦福 Algorithms: Design and Analysis 1 第三周笔记
来自斯坦福网站的Algorithms: Design and Analysis,与目前coursera上的版本内容没有变化,不过时间安排略有不同。
1 LINEAR-TIME SELECTION
selection问题指的是,给定一个长度为n的无序数组,选取其中第k大的数。为了分析简单假定每个数字不重复。
1.1 randomized selection
1.1.1 算法
简单的方法可以直接将数组排序选取第k个数作为输出。但还有更简单的方式,可以回忆快排partition的操作:partition操作结束后,数组分为左边,右边以及pivot三个部分。因此第k个数的分布也对应三种情况。于是利用递归我们就得到了一个选择第k大的数的随机选择的算法:
1.1.2 正确性
可以利用归纳法证明算法的正确性,证明过程与快排时的证明类似:
- 当n=1时,算法能正确得到第k大的数。
- 假设当n=k1,k2时算法能得到第k大的数。因此在n=k3=k1(左边长度)+k2(右边长度)+1(pivot)时,如果k<=k1,则相当于是n=k1时,显然成立。如果k = k1+1则选到pivot。如果k>k1+1,相当于是n=k2时的情况,也是成立的。因此算法正确性得证。
1.1.3 复杂度分析
算法的运行时间一定程度上依然依赖于pivot的选择。比如如果是最坏的情况(已排序的数组,每次第一个作为pivot),运行时间依然是 O ( n 2 ) O(n^{2}) O(n2)。但是假如pivot选得足够好,能够利用master method的话,那么可以得到这个算法的运行时间是 O ( n ) O(n) O(n)。
事实上,这个算法的平均情况下运行时间是 O ( n ) O(n) O(n)。
证明如下:由于每次递归剩下的数组长度无法得知,因此不好使用类似快排里证明的方法。这里使用了一个新的形式,定义了一个phase j,每个phase表示当前剩下的数组长度所在的长度范围为( 3 4 j + 1 n , 3 4 j n ) \dfrac{3}{4}^{j+1}n, \dfrac{3}{4}^{j}n) 43j+1n,43jn)之间。
其中 X j X_{j} Xj表示在phase j里进行了几次调用。可以先重点计算一下这个变量的期望 E [ X j