leetcode之TopK(快排/堆排序)
- 快排思想
并不需要把全部都排序好,只用分组快排,快排其实是把小于基准数的所有数放在左边,大于的数都放在右边,只要找到这个基准数在快排后的下标,若下标<k-1,则将左边那组继续快排,若>k-1,则将右边那组快排。
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if (k == 0 || arr.length == 0) {
return new int[0];
}
return quickSearch(arr, 0, arr.length - 1, k - 1);
}
private int[] quickSearch(int[] nums, int lo, int hi, int k) {
int j = partition(nums, lo, hi);
if (j == k) {
return Arrays.copyOf(nums, j + 1);
}
return j > k? quickSearch(nums, lo, j - 1, k): quickSearch(nums, j + 1, hi, k);
}
private int partition(int[] nums, int lo, int hi) {
int v = nums[lo];
int i = lo, j = hi + 1;
while (true) {
while (++i <= hi && nums[i] < v);
while (--j >= lo && nums[j] > v);
if (i >= j) {
break;
}
int t = nums[j];
nums[j] = nums[i];
nums[i] = t;
}
nums[lo] = nums[j];
nums[j] = v;
return j;
}
}
- 堆排序
使用Java自带的PriorityQueue的方法,只需要k个值,每次往堆中添加时,若不满足条件则不添加。
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if(arr.length==0||k==0) return new int[0];
Queue<Integer> heap=new PriorityQueue<>(k,(i1,i2)->Integer.compare(i2,i1));
for (int e:
arr) {
if (heap.isEmpty() || heap.size()<k || e<heap.peek()){
heap.offer(e);
}
if(heap.size()>k){
heap.poll();
}
}
int[] nums=new int[heap.size()];
int j=0;
for (int e:
heap ) {
nums[j++]=e;
}
return nums;
}
}