Heap 堆
定义
Heap 本质是一个用 Array 实现的 Complete Binary Tree, 这个 Tree 的 root 节点代表整个 Heap 里的最大(max heap) 或者最小值(min heap)。
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
常用方法 (Common APIs)
- peek(): 查看堆顶元素 O(1)
- poll(): 拿到堆顶元素 O(logN)
- offer(): 添加元素 O(logN)
- size(): 堆中元素总数
- isEmpty(): 判断是否为空
Online vs Offline Algorithm
- Online Algorithm (using Heap): 针对一组流数据,没有固定长度,可以随时根据需求 scalable
- Offline Algorithm (using Sorting): 针对一组固定长度数据,每次 scale 后要重新计算
Top K 问题 常见解题方式
- Sorting O(nlogn): Sort the array and get the kth element
- Max Heap O(n + klogn): Heapify the array, then poll k times
- Min Heap O(nlogk)
- Maintain a size k min heap
- Add element to min heap if greater than or equal to top element, adjust size if necessary
- At the end top of heap is the kth largest
Q215 例题: Kth Largest Element in an Array (Top K 问题)
High Level Idea
online Algorithm
- Initialize a min heanp
- For each element x in the array
- offer to heap if heap size < k or x >= top of heap
- Adjust heap size if necessary
- Return the top of heap
代码
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
for (int x : nums) {
if (minHeap.size() < k || x >= minHeap.peek()) {
minHeap.offer(x);
}
if (minHeap.size() > k) {
minHeap.poll();
}
return minHeap.peek();
}
}
Q23 例题: Merge K Sorted Lists
对于一个固定数量
简单解题方法: 使用 K 个指针,谁小移动谁。
找出最小值
现在有 k 个指针,每次添加并移动最小的指针,如何每次找到最小值:
- Liniear Scan O(k)
- Simple Sorting O(klogk)
- Min Heap O(logk)
High Level Idea
时间复杂度 O(nlogk), n = 所有 node 总数
online Algorithm
- Initialize min heap with all List head references
- While heap is not empty
- Poll out top of heap (smallest pointer)
- Add it to result list
- Add its next node if there exists
代码
public ListNode mergeKLists(ListNode[] lists) {
PriorityQueue<ListNode> minHeap = new PriorityQueue<>((a, b) -> a.val - b.val);
for (ListNode list: lists) {
if (list != null) {
minHeap.offer(list);
}
}
ListNode res = new LisNode(0), cur = res; // Dummy head tech for linked list
while (!minHeap.isEmpty()) {
ListNode top = minHeap.poll();
cur.next = top;
cur = cur.next;
if(top.next != null) {
minHeap.offer(top.next);
}
}
return res.next;
}
更多例题
- Top K Frequent Elements (347)
- Meeting Rooms II (253)
- Find Median From Data Stream (295)
- Reorganize String (767)
- Kth Largest Element in a Stream (703)
来源
- Heap 堆解题套路【LeetCode 刷题套路教程 6】: https://www.youtube.com/watch?v=vIXf2M37e0k&list=PLV5qT67glKSErHD66rKTfqerMYz9OaTOs&index=6