题目描述:
思路:两种常用的方法:1.先存储k个数,当后续数字大于其中最大的数时,替换掉其中最大的数,最后剩下的k个数就是结果。2. 用快排的思路,先随机取一个数,将大于他的放到左面,小于他的放到右面,返回当前数字的当前位置,如果比k大,继续向左执行,如果比k小继续向右执行。如果正好相等,则复制到当前前k个数并返回。
采用最大堆
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if (k==0)return new int[0];
int[] result=new int[k];
Queue<Integer> queue =new PriorityQueue<>((v1,v2)->v2-v1);
for(int i=0;i<k;i++){
queue.add(arr[i]);
}
int top=queue.peek();
for(int i=k;i<arr.length;i++){
if(arr[i]<top){
queue.remove();
queue.add(arr[i]);
top=queue.peek();
}
}
for(int i=0;i<k;i++){
result[i]=queue.remove();
}
return result;
}
}
采用快排思想:
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if(k==0)return new int[0];
queueSelect(arr,0,arr.length-1,k);
int[] result=new int[k];
for(int i=0;i<k;i++){
result[i]=arr[i];
}
return result;
}
private void queueSelect(int[] arr,int start,int end,int k){
if(start<end){
int pivot=partition(arr,start,end);
if(pivot ==k-1){
return;
}else if(pivot >k-1){
queueSelect(arr,start,pivot-1,k);
}else{
queueSelect(arr,pivot+1,end,k);
}
}
}
private int partition(int[] arr,int start,int end){
int tem=arr[start];
while(start<end){
while(start<end&&arr[end]>=tem){
end--;
}
swap(arr,start,end);
while(start<end&&arr[start]<=tem){
start++;
}
swap(arr,start,end);
}
return start;
}
private void swap(int[] arr,int low,int high){
int tem=arr[low];
arr[low]=arr[high];
arr[high]=tem;
}
}