5. Kth Largest Element (快排之思)
起因源于我与同事争论,find kth largest element是O(n)的复杂度还是O(nlogn) 。我一直认为find kth largest element 最优解与快排同源,所以应该是O(nlogn),事实证明我是错的,实际的解法是快速选择,O(n)最优情况,O(n2)最差情况。
解法都大同小异如下: (我取了中间点作为pivot,最简单的做法是取头或者尾作为pivot)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
关键在于复杂度的分析。
快排:
快排的(average)复杂度之所以为O(nlogn),因为每次partition需要O(n),
最差情况:每次partition正好为[]和[0..n]
,也就是T(n)=T(n-1)+T(0)+O(n) -> T(n)=T(n-1)+O(n)-> T(n)=O(n^2)
最优情况:每次partition正好为[0..n/2-1]和[n/2..n]
,也就是T(n)=2T(n/2)+O(n) -> T(n)=O(nlogn)
同时也可以简单理解为最差需要partition O(n)次而最优只需要partition O(logn)次
快速选择:
快速选择的(average)复杂度之所以为O(n),因为每次递归只需要partition整个array的一半,
最差情况:依旧与快排类似,如果每次pivot都选择了最小或者最大,那么还是需要O(n2)去完成整个操作
最优情况:如果pivot正好选择了中间值,那么T(n)=T(n/2)+O(n) -> T(n)=2O(n) -> T(n)=O(n)