输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
示例 1:
输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]
示例 2:
输入:arr = [0,1,2,1], k = 1
输出:[0]
解题思路:
1、排序后返回前k个元素(不推荐)
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
Arrays.sort(arr);
return Arrays.copyOf(arr,k);
}
}
2、堆排序(大顶堆)
先存入前k个元素,存完后每次比较堆顶元素与当前索引元素,如果堆顶元素大于当前元素,出堆后存入当前元素。
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if(k==0) return new int[0];
// 大顶堆
PriorityQueue<Integer> A = new PriorityQueue<>(k,(x,y)->(y-x));
for(int i=0;i<arr.length;i++){
if(i<k){
A.add(arr[i]);
continue;
}
if(A.peek()>arr[i]){
A.poll();
A.add(arr[i]);
}
}
int[] result = new int[k];
for(int i=0;i<k;i++){
result[i] = A.poll();
}
return result;
}
}
3、快速排序(分治法)
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
quickSort(arr,0,arr.length-1,k);
return Arrays.copyOf(arr,k);
}
void quickSort(int[] arr,int left,int right,int k){
if(left>=right) return;
int i=left,j=right;
while(i<j){
while(i<j && arr[left]<=arr[j]) j--;
while(i<j && arr[left]>=arr[i]) i++;
swap(arr,i,j);
}
swap(arr,left,i);
if(i<k) quickSort(arr,i+1,right,k);
if(i>k) quickSort(arr,left,i-1,k);
}
void swap(int[] arr,int i,int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
如何new一个大顶堆
PriorityQueue<Integer> A = new PriorityQueue<>(k,(x,y)->(y-x));
题目来源
作者:Krahets
链接:https://leetcode.cn/leetbook/read/illustration-of-algorithm/ohvl0d/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。