面试必考真题-算法篇 牛客网
堆 分治
题目描述
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
题目分析
利用快速排序,将数组按照标兵即数组的第一个元素,对数组分成两部分,左侧都小于标兵,右侧都大于标兵。如果右侧的不足K个数,则继续从数组左半部分中进行寻找,如果右侧的元素数量大于K个数,则继续从右侧进行寻找。这样可以避免对数组进行全部排序,提高效率。
下面是Java代码
import java.util.*;
public class Finder {
public int findKth(int[] a, int n, int K) {
// write code here
if(a.length == 0){
return 0;
}
return quickfind(a,0,n-1,K);
}
private int quickfind(int[] a,int left ,int right,int k){
int i = left;
int j = right;
int mark = a[left];
while(i < j){
while(i<j && a[j] >=mark){
--j;
}
if(i < j){
a[i++] = a[j];
}
while(i<j && a[i]<=mark){
++i;
}
if(i < j){
a[j--] = a[i];
}
}
a[i] = mark;
//哨兵右侧比他大的数字个数
int big_num = right - i;
//如果哨兵刚好是第K大的数
if(k - big_num -1 == 0){
return mark;
}else if(k -big_num -1 >0){
//如果右侧数字个数不够K个,则从左侧找第k-big_num-1大的数
return quickfind(a, left , i - 1, k-big_num -1);
}else{
//如果右侧数字个数比K多,则在右侧找第K大的数
return quickfind(a,i+1,right,k);
}
}
}