class Solution {
// 堆排序 ,利用PriorityQueue,构建大顶堆。队首元素为最大的。(队列只保证队首为最大的,不是全排序)
// 时间复杂度:O(nlogk),大根堆维护k个数,每次插入,删除logk,最坏情况下n个数都会插进去一遍。
// 空间复杂度:O(k),大根堆里最多k个数
public int[] getLeastNumbers(int[] arr, int k) {
int[] res=new int[k];
if (k == 0) {
return res;
}
// PriorityQueue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>() {
// public int compare(Integer num1, Integer num2) {
// return num2 - num1;
// }
// });
// PriorityQueue<Integer> queue=new PriorityQueue<>((n1, n2)->{return n2-n1;} );
// 注意右边泛型的尖括号必须加,要不通不过语法检查
PriorityQueue<Integer> queue=new PriorityQueue<>((n1, n2)-> n2-n1);
for(int i=0;i<k;i++){
queue.offer(arr[i]);
}
for (int i = k; i < arr.length; i++) {
if(arr[i]<queue.peek()){
queue.poll();
queue.offer(arr[i]);
}
}
for(int i=0;i<k;i++){
res[i]=queue.poll();
}
return res;
}
}
快排:
// 快排思想 O(nlogn),O(n)
public int[] getLeastNumbers(int[] arr, int k) {
if(arr==null||arr.length==0){
return arr;
}
quickSort(arr,0,arr.length-1);
return Arrays.copyOf(arr,k);
}
public void quickSort(int[] arr,int l,int r){
if(l>=r){
return;
}
int i=l,j=r;
while(i<j){
while(i<j&&arr[j]>=arr[l]){
j--;
}
while(i<j&&arr[i]<=arr[l]){
i++;
}
// 交换
int temp=arr[j];
arr[j]=arr[i];
arr[i]=temp;
}
// 本轮结束,最后交换基准到中间正确位置
int temp=arr[j];
arr[j]=arr[l];
arr[l]=temp;
// 对左右子序列递归
quickSort(arr,l,j-1);
quickSort(arr,j+1,r);
}
}
优化的快排
// 优化的快排,O(n),O(logn)
public int[] getLeastNumbers(int[] arr, int k) {
if(arr==null||arr.length==0||k>=arr.length){
return arr;
}
return quickSort(arr,0,arr.length-1,k);
}
public int[] quickSort(int[] arr,int l,int r,int k){
int i=l,j=r;
while(i<j){
while(i<j&&arr[j]>=arr[l]){
j--;
}
while(i<j&&arr[i]<=arr[l]){
i++;
}
// 交换
int temp=arr[j];
arr[j]=arr[i];
arr[i]=temp;
}
// 本轮结束,最后交换基准到中间正确位置
int temp=arr[j];
arr[j]=arr[l];
arr[l]=temp;
// 这次只用找其中一个,注意k不可以大于等于arr.length。因为j最大为r,为arr.length-1
if(k<j)
return quickSort(arr,l,j-1,k);
if(k>j)
return quickSort(arr,j+1,r,k);
return Arrays.copyOf(arr,k);
}