快排的平均时间复杂度为nlog2n
描述
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
示例1
输入:
[1,3,5,2,2],5,3
返回值:
2
1)方法一:快排
/**
*
* @param a int整型一维数组
* @param n int整型
* @param K int整型
* @return int整型
*/
function findKth( a , n , K ) {
// 快速排序 排k趟,逆序
return Quick(a, 0, n-1, K);
}
function Quick(a, low, high, k){
// 注意:前面写 if(low<high),则不能通过所有用例
let l = low, h = high;
let p = a[l];
while(l<h){
while(l<h && a[h]<p){h--;}
a[l] = a[h];
while(l<h && a[l]>p) {l++;}
a[h] = a[l];
}
a[l] = p;
if((l+1) == k){
return a[l];
}else if((l+1) < k){
return Quick(a,l+1,high,k);
}else{
return Quick(a,low,l-1,k);
}
}
module.exports = {
findKth : findKth
};
平均时间复杂度:O(Nlog2N)
2)方法二:堆排序
时间复杂度:O(KlogN),构建一次最大堆O(log2N),访问K次,比整体排序时间更短
思路:
- 先将前k个元素创建为一个小顶堆,堆顶是这k个元素中最小的元素;
- 依次遍历第k+1到第n之间的元素;
- 若比堆顶k大,则将其放入到堆顶;
- 最后堆中的k个元素为前k大元素,堆顶为第k大元素;