一、1046.最后一块石头的重量
题目描述
给定一组石头,每次选择两块最重的进行碰撞。如果重量相同则都粉碎;否则轻的粉碎,重的变为差值。求最后剩下石头的重量。
思路解析
核心在于每次都要取出当前最大的两个数。如果用普通数组排序,每次插入新元素后都需要重新排序,效率较低。使用大根堆(Max Heap)可以高效地获取最大值,每次操作的时间复杂度仅为 O(logN)。
参考实现
// 时间复杂度 O(n log n),空间复杂度 O(n)
class Solution {
public int lastStoneWeight(int[] stones) {
// 创建大根堆,比较器确保大的元素在顶部
PriorityQueue<Integer> queue = new PriorityQueue<>((a, b) -> b - a);
// 将所有石头加入堆中
for (int stone : stones) {
queue.offer(stone);
}
// 模拟碰撞过程
while (queue.size() > 1) {
int y = queue.poll(); // 最重
int x = queue.poll(); // 次重
if (y - x > 0) {
queue.offer(y - x); // 剩余部分放回堆中
}
}
return queue.isEmpty() ? 0 : queue.poll();
}
}
二、703. 数据流中的第 K 大元素
题目描述
设计一个类,支持动态添加数字并返回当前数据流中的第 K 大元素。
思路解析
维护一个大小为 K 的小根堆(Min Heap)。堆中保存的是当前已知的最大的 K 个数。当新元素加入时,如果堆已满且新元素大于堆顶,则替换堆顶。这样堆顶始终是当前第 K 大的数。
参考实现
// 时间复杂度 O(n log k),空间复杂度 O(k)
{
PriorityQueue<Integer> heap;
k;
{
.k = k;
.heap = <>(k);
( num : nums) {
add(num);
}
}
{
heap.offer(val);
(heap.size() > k) {
heap.poll();
}
heap.peek();
}
}


