1.二叉堆
思路:将节点一个一个的插入二叉堆(优先队列),当堆中元素多于k个时,删除堆顶元素。每个节点都过一遍之后,再取堆顶元素。
注意java中的优先队列默认是小顶堆,如果找的是第k个最大元素,则应该是把小的数字删掉留下大的,所以应该是使用小顶堆
如果是找第k个最小的元素,则应该是把大的删掉,则应该用的是大顶堆
java中使用大顶堆、小顶堆的代码
小顶堆
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, (a,b)->a-b);
//括号里是重写比较器的lambda表达式,k是初始化大小
//小顶堆可以省略
大顶堆
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, (a,b)->b-a);
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> que = new PriorityQueue<>();
for (int num : nums) {
que.offer(num);
if (que.size()>k){
que.poll();
}
}
return que.peek();
}
2.快速选择算法
2.1回顾快速排序算法
public void sort(int[] nums) {
quickSort(nums, 0, nums.length - 1);
}
public void quickSort(int[] nums, int lo, int hi){
if (hi<=lo) return;
int partition = partition(nums, lo, hi);
quickSort(nums,lo,partition-1);
quickSort(nums,partition+1,hi);
}
public int partition(int[] nums, int lo, int hi){
int pivot = nums[lo];
int i = lo;
int j = hi+1;
while (true){
while (nums[++i]<pivot){
if (i==hi) break;
}
while (nums[--j]>pivot){
if (j==lo) break;
}
if (i>=j) break;
swap(nums,i,j);
}
swap(nums,lo,j);
return j;
}
public void swap(int[] nums,int i,int j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
2.2快速选择算法
public int findKthLargest(int[] nums, int k) {
k = nums.length - k;
int lo = 0, hi = nums.length - 1;
while (lo<=hi){
int partition = partition(nums, lo, hi);
if (partition<k){
lo = partition+1;
}else if (partition>k){
hi = partition - 1;
}else {
return nums[partition];
}
}
return -1;
}
总结
遇到题目优先选择二叉堆,快速排序算法熟记