本题目借助快排思想,算法描述:
- a为待排序数组,n为数组长度
- 问题转换:把第k大数字转换成第l小数字,比如:
n=5,k=1
,那么l=n-k+1=5
,也就是第5小的数字,其下标l_i=5-1=4
。 - 取
a[n-1]
作为 pivot - 用快排的思路,把
< pivot
的元素放到 pivot 左边,把>= pivot
的元素放到 pivot 右边,得到pivot的下标:pivot_i
- 如果
pivot_i < l_i
,则说明被查找的数字可能在右边,对右边重复2-5步骤 - 如果
pivot_i > l_i
,则说明被查找的数字可能在左边,对左边重复2-5步骤
代码:
|
|
算法复杂度分析:
最好情况:
k > n
,即要找的数字超出了数组所能给出的范围,复杂度O(1)。- 第一次分区的pivot就是要找的数字,遍历n-1次,复杂度O(n)。
最坏情况:
- 每次pivot分区极不均匀——pivot的左分区元素数量为原始分区数量-1,或者pivot的右分区数量为原始分区数量-1——且分区大小要变成1之后,才能够找到要找的元素。
- 比如 k=n,且这个数组已经是有序了。那么每次遍历的次数是
(n-1)+(n-2)+(n-3)+...+1=n(n-1)/2
,即O(n^2)。
平均情况:
- 不知怎么分析
评论