算法思想
取一个pivot,以pivot将原数组划分为两部分大小分别是x和y,确定了pivot的位置,现在知道pivot是第y+1大,如果k比y+1小,继续往右边找,如果k比y+1大,往左边找,如果k等于y+1,说明找到了。
主定理(master theorem)
假设有递推表达式 T(n)=aT(nb)+f(n)T(n)=aT(\frac n b)+f(n)T(n)=aT(bn)+f(n) ,其中nnn为问题规模,aaa为递推的子问题数量, nb\frac n bbn为每个子问题的规模(假设每个子问题的规模基本一样),f(n)f(n)f(n)为递推以外进行的计算工作。
a≥1,b>1a≥1,b>1a≥1,b>1为常数,f(n)f(n)f(n) 为函数,T(n)T(n)T(n)为非负整数。则有以下结果(分类讨论):
a. 若f(n)=O(nlogba−ϵ),ϵ>0,则T(n)=Θ(nlogba)若f(n)=O(n^{log_ba-\epsilon}),\epsilon>0,则T(n)=\Theta(n^{log_ba})若f(n)=O(nlogba−ϵ),ϵ>0,则T(n)=Θ(nlogba)。
b. 若f(n)=Θ(nlogba),则T(n)=Θ(nlogbalogn)若f(n)=\Theta(n^{log_ba}),则T(n)=\Theta(n^{log_ba}logn)若f(n)=Θ(nlogba),则T(n)=Θ(nlogbalogn)。
c. 若f(n)=Ω(nlogba+ϵ),ϵ>0,且对于某个常数c<1和所有充分大的n有af(nb)≤cf(n),那么T(n)=Θ(f(n))若f(n)=\Omega(n^{log_ba+\epsilon}),\epsilon>0,且对于某个常数c<1和所有充分大的n有af(\frac nb) \leq cf(n),那么T(n)=\Theta(f(n))若f(n)=Ω(nlogba+ϵ),ϵ>0,且对于某个常数c<1和所有充分大的n有af(bn)≤cf(n),那么T(n)=Θ(f(n))。
证明
上面算法每次规模缩小一半,除此以外需要n次比较,所以可以写出递推表达式是T(n)=T(n2)+nT(n) = T(\frac n 2)+nT(n)=T(2n)+n。
由主定理可知,
a=1,b=2,logab=0a=1,b=2,log_ab=0a=1,b=2,logab=0
有f(n)=n=Ω(nϵ),ϵ取1,c取12,所以T(n)=Θ(n)f(n)=n=\Omega(n^\epsilon), \epsilon取1,c取\frac 12,所以T(n)=\Theta(n)f(n)=n=Ω(nϵ),ϵ取1,c取21,所以T(n)=Θ(n)。
代码实现
private int partition(int[] nums, int l, int r) {
int pivot = nums[l];
while (l < r) {
while (l < r && pivot <= nums[r]) r--;
if (l < r) nums[l] = nums[r];
while (l < r && pivot >= nums[l]) l++;
if (l < r) nums[r] = nums[l];
}
nums[l] = pivot;
return l;
}
public int findKthLargest(int[] nums, int l, int r, int k) {
if (l == r && k == 1) return nums[l];
int pivotIndex = partition(nums, l, r);
int y = r - pivotIndex;
if (k < y + 1) return findKthLargest(nums, pivotIndex + 1, r, k);
else if (k > y + 1) return findKthLargest(nums, l, pivotIndex - 1, k - y - 1);
else return nums[pivotIndex];
}
本文深入探讨了快速选择算法的思想与应用,通过选取一个基准元素(pivot),将数组划分并找到第k大的元素。同时,详细解析了主定理(Master Theorem),这是一种用于分析递归算法复杂度的强大工具,适用于形式为T(n)=aT(n/b)+f(n)的递推表达式。
4531

被折叠的 条评论
为什么被折叠?



