在数组中找第K大的元素
LeetCode21 Medium
我们要找第 K 大的元素,如果我们找使用大堆的话那么就会造成这个堆到底需要多大的,而且哪一个是第 K 的的元素我们不知道是哪一个索引,我们更想要的结果就是根节点
就是我们要找的值,所以我们可以使用 小堆,使用小堆的好处就是,我们可以用到小堆的性质:根节点最小。使用这个我们在结合 if 判断一下,就可以实现这个效果了!
java
import java.util.PriorityQueue;
public class Solution {
public int findKthLargest(int[] nums, int k) {
if(k>nums.length){
return -1;
}
int len = nums.length;
// 使用一个含有 k 个元素的最小堆
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, (a, b) -> a - b);
for (int i = 0; i < k; i++) {
minHeap.add(nums[i]);
}
for (int i = k; i < len; i++) {
// 看一眼,不拿出,因为有可能没有必要替换
Integer topEle = minHeap.peek();
// 只要当前遍历的元素比堆顶元素大,堆顶弹出,遍历的元素进去
if (nums[i] > topEle) {
minHeap.poll();
minHeap.offer(nums[i]);
}
}
return minHeap.peek();
}
}
小结一下:
- K多大就建立多大固定大小的堆
- 找最大用小堆,
- 只有比根元素大的才让进入堆。
合并K个排序链表
合并K个排序链表 Hard
priorityQueue.offer(tail.next) 这个操作保证了合并后的链表也是有序的。
java
Class solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
// 创建一个最小堆
PriorityQueue<ListNode> priorityQueue = new PriorityQueue<>(Comparator.comparing(node -> node.val));
for (ListNode list : lists) {
if (list != null) {
priorityQueue.add(list);
}
}
// 记录头节点
ListNode dummy = new ListNode(0);
ListNode tail = dummy;
// 进行排序
while (!priorityQueue.isEmpty()) {
tail.next = priorityQueue.poll();
tail = tail.next;
if (tail.next != null) {
priorityQueue.offer(tail.next);
}
}
return dummy.next;
}
}