掌握优先级队列的核心思想,高效解决TopK/中位数等高频算法问题!
一、最后一块石头的重量
问题描述
每次选择最重的两块石头碰撞,若重量相同则消失,不同则留下差值。求最终剩余石头的重量。
示例:
输入:[2,7,4,1,8,1] → 碰撞过程:
- 8 vs 7 → 余1 →
[2,4,1,1,1] - 4 vs 2 → 余2 →
[1,1,1,2] - 2 vs 1 → 余1 →
[1,1,1] - 1 vs 1 → 消失 → 最终结果:
1
解题思路
- 大顶堆存储:将所有石头放入大顶堆(Java的
PriorityQueue默认小顶堆,需重写比较器) - 循环碰撞:每次弹出堆顶两个元素进行碰撞
- 差值入堆:若碰撞后剩余重量>0,将差值重新入堆
- 终止条件:堆中元素≤1时停止
代码实现
class Solution {
public int lastStoneWeight(int[] stones) {
PriorityQueue<Integer> heap = new PriorityQueue<>((a, b) -> b - a); // 大顶堆
for (int stone : stones) heap.offer(stone);
while (heap.size() > 1) {
int y = heap.poll(); // 最重石头
int x = heap.poll(); // 次重石头
if (y > x) heap.offer(y - x); // 碰撞后剩余
}
return heap.isEmpty() ? 0 : heap.peek();
}
}
二、数据流中的第 K 大元素
问题特点
- 动态数据流:持续添加新元素
- 实时获取当前第K大的元素
解决方案:小顶堆维护TopK
- 初始化:创建大小为K的小顶堆
- 添加元素:
- 堆未满时直接入堆
- 堆满后,若新元素>堆顶则替换堆顶
- 获取结果:堆顶即第K大元素
复杂度分析
- 时间复杂度:
add()操作O(logK)O(\log K)O(logK),get()操作O(1)O(1)O

最低0.47元/天 解锁文章
2万+

被折叠的 条评论
为什么被折叠?



