《算法导论》笔记 第9章 9.3最坏情况线性时间选择
【笔记】
SELECT最坏运行情况是线性的。
【练习】
9.3-1 在算法SELECT中,输入元素被分为每组5个元素。如果它们被分为每组7个元素,该算法会仍然以线性时间工作吗?证明如果分成每组3个元素,SELECT无法在线性时间内运行。
考虑每组分为k个元素。则大于或小于中位数的中位数的数至少为
因此在最坏情况下SELECT将处理最多n-(n/4-k)=3n/4+k个元素。
递归式
用代换法解决,假设算法是线性的,猜测有T(n)<=cn。
其中最后只在k>=4时成立。
因此该算法对4个及4个以上的分组是线性的。当k=3时该算法的复杂度是Ω(nlgn)。
9.3-2 分析SELECT,并证明如果n>=140,则至少有n/4个元素大于中位数的中位数x,并且至少有n/4个元素小于x。
9.3-3 假定元素的值不同,说明如何才能使快速排序在最坏情况下以O(nlgn)时间运行。
在快速排序中,使用完美分区即可在最坏情况下有O(nlgn)复杂度。每次以线性时间选出区间的中位数即可。
9.3-4 假设对一个含有n个元素的集合,某算法只能用比较来确定第i小的元素。证明:无需另外的比较操作,它也能找到比i小的i-1个元素和比i大的n-i个元素。
9.3-5 假设已经有了一个用于求解中位数的黑箱子程序,它在最坏情况下需要线性运行时间。写出一个能解决任意顺序统计量的选择问题的线性时间算法。
用该黑箱算法做9.2中算法的划分,T(n)<=T(n/2)+O(n)+O(n)。
9.3-6 对一个含有n个元素的集合来说,所谓k分位数,就是能把已排序的集合分成k个大小相等的集合的k-1个顺序统计量。给出一个能列出某一集合的k分位数的O(nlgk)时间的算法。
9.3-7 给出一个O(n)时间的算法,在给定一个有n个不同数字的集合S以及一个正整数k<=n后,它能确定出S中最接近其中位数的k个数。
找到n个数的中位数,将n个数都减去其中位数,选出绝对值第k小的数,依次扫描n个数,其中绝对值小于等于第k小数的值加上中位数的既是最接近中位数的数。
9.3-8 设X[1..n]和Y[1..n]为两个数组,每个都包含n个已排好序的数。给出一个求数组X和Y中所有2n个元素的中位数的、O(lgn)时间算法。
int findMedian(int A[],int B[],int n,int low,int high) { if (low > high) return NOT_FOUND; else { int k = (low+high)/2; if (k==n && A[n]<=B[1]) return A[n]; else if (k<n && B[n-k]<=A[k] && A[k]<=B[n-k+1]) return A[k]; else if (A[k] > B[n-k+1]) return findMedian(A,B,n,low,k-1); else return findMedian(A,B,n,k+1,high); } } int twoArrayMedian(int X[],int Y[],int n) { int median = findMedian(X,Y,n,1,n); if (median==NOT_FOUND) median = findMedian(Y,X,n,1,n); return median; }我们要取下中位数,注意到一个数x是中位数,当且仅当有n-1个数比x小,有n个数比x大,我们首先假设中位数在数组A中,二分中位数可能在的位置。
假设中位数所在区间为[L,R],k为(L+R)/2。若A[k]是中位数,数组A中有k-1个数比A[k]小,n-k个数比A[k]大。若B中有n-k个数比A[k]小,有k个数比A[k]大,则A[k]是中位数。
由于B是已排序的,因此B[n-k]<=A[k]<=B[n-k+1]。
若A[k]>B[n-k+1],则比A[k]小的数至少有n个,所以中位数小于A[k],因此在区间[L,k-1]中。
反之则在区间[k+1,R]中。
若L>R,则中位数不在A中,对B数组进行同样的二分操作即可。
9.3-9 给定各口井的x坐标和y坐标,应如何选择主管道的最优位置?证明最优位置可以在线性时间内确定。
取y的中位数即可。大概吧。