题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
code
方法1:
利用PriorityQueue的最大堆
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> res=new ArrayList<>();
if(input==null||input.length==0||k<=0||k>input.length){
return res;
}
PriorityQueue<Integer> queue=new PriorityQueue<>(k,new Comparator<Integer>(){
@Override
public int compare(Integer num1,Integer num2){
return num2-num1;
}
});
for(int i=0;i<input.length;i++){
if(queue.size()<k){
queue.offer(input[i]);
}else if(queue.peek()>input[i]){
queue.poll();
queue.offer(input[i]);
}
}
for(int num:queue){
res.add(num);
}
return res;
}
方法2:
剑指offer上的思路:利用快排的单次调整,找到mid==k-1的位置,也就找到了前k个数
/*
时间复杂度为n,剑指offer上的168页
*/
public ArrayList<Integer> GetLeastNumbers_Solution2(int [] input, int k) {
ArrayList<Integer> res=new ArrayList<>();
//这里不要忘了判断 k>input.length
if(input==null||input.length==0||k<=0||k>input.length){
return res;
}
int start=0;
int end=input.length-1;
int index=partition(input,start,end);
while (index!=(k-1)){
if(index<k){
index=partition(input,index+1,end);
}else{
index=partition(input,start,index-1);
}
}
for (int i=0;i<k;i++){
res.add(input[i]);
}
return res;
}
private int partition(int[] input, int start, int end) {
int num=input[start];
while (start<end){
while (start<end&&input[end]>=num){
end--;
}
if(start<end){
input[start++]=input[end];
}
while (start<end&&input[start]<=num){
start++;
}
if(start<end){
input[end--]=input[start];
}
}
input[start]=num;
return start;
}