优先队列(PriorityQueue)在基础的 Top-K 之外,还能解决数据流中位数、任务调度、图的最短路径优化等复杂问题。本篇聚焦堆的进阶应用与多堆协作模式。
一、Java PriorityQueue 速查
Mermaid · 渲染中(下方为源码)
graph LR A[优先队列] --> B[Top-K] A --> C[数据流中位数] A --> D[任务调度]
// 最小堆(默认)
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
// 最大堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
// 自定义
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
// 操作
pq.offer(x); // 入堆 O(log n)
pq.peek(); // 查看堆顶 O(1)
pq.poll(); // 弹出堆顶 O(log n)
pq.size(); // 大小 O(1)二、数据流中位数(LeetCode 295)
用两个堆:大顶堆存较小半,小顶堆存较大半。
class MedianFinder {
PriorityQueue<Integer> lo = new PriorityQueue<>(Collections.reverseOrder()); // 大顶堆
PriorityQueue<Integer> hi = new PriorityQueue<>(); // 小顶堆
void addNum(int num) {
lo.offer(num);
hi.offer(lo.poll());
if (hi.size() > lo.size()) lo.offer(hi.poll());
}
double findMedian() {
if (lo.size() > hi.size()) return lo.peek();
return (lo.peek() + hi.peek()) / 2.0;
}
}