
解题思路:
- 统计频率: 使用哈希表统计每个元素的出现频率。
- 维护最小堆: 遍历哈希表,将元素及其频率存入最小堆,堆的大小保持为 k。当堆的大小超过 k 时,如果当前元素频率大于堆顶,弹出堆顶并存入当前元素及其频率。
- 提取结果: 堆中剩余的元素即为前 k 个高频元素。
Java代码:
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums)
map.put(num, map.getOrDefault(num, 0) + 1);
PriorityQueue<Map.Entry<Integer, Integer>> minHeap = new PriorityQueue<>(
(a, b) -> a.getValue() - b.getValue()
);
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (minHeap.size() < k) {
minHeap.offer(entry);
} else if (entry.getValue() > minHeap.peek().getValue()) {
minHeap.poll();
minHeap.offer(entry);
}
}
int[] result = new int[k];
for (int i = 0; i < k; i++)
result[i] = minHeap.poll().getKey();
return result;
}
}
复杂度分析:
- 时间复杂度: 每个元素插入和删除的复杂度为 O(log k),总共有 n 个元素,因此总复杂度为 O(n log k)。
- 空间复杂度: 哈希表存储 O(n),堆存储最多 k 个元素,总复杂度为 O(n)。

解题思路:
- 数据结构设计:
- 最大堆(maxHeap):存储较小的一半元素,堆顶为最大值。
- 最小堆(minHeap):存储较大的一半元素,堆顶为最小值。
- 平衡条件:maxHeap 的大小最多比 minHeap 大 1,或两者大小相等。
- 添加元素逻辑:
- 若新元素小于等于 maxHeap 的堆顶,插入 maxHeap;否则插入 minHeap。
- 平衡调整:
-
- 若 maxHeap 的大小超过 minHeap 的大小 + 1,将 maxHeap 的堆顶移到 minHeap。
-
- 若 minHeap 的大小超过 maxHeap,将 minHeap 的堆顶移到 maxHeap。
- 查找中位数:
- 若两堆大小相等,返回两堆顶的平均值。
- 否则,返回 maxHeap 的堆顶(奇数情况)。
Java代码:
public class MedianFinder {
private PriorityQueue<Integer> maxHeap;
private PriorityQueue<Integer> minHeap;
public MedianFinder() {
maxHeap = new PriorityQueue<>((a, b) -> b - a);
minHeap = new PriorityQueue<>();
}
public void addNum(int num) {
if (maxHeap.isEmpty() || num <= maxHeap.peek()) {
maxHeap.offer(num);
} else {
minHeap.offer(num);
}
if (maxHeap.size() > minHeap.size() + 1) {
minHeap.offer(maxHeap.poll());
} else if (minHeap.size() > maxHeap.size()) {
maxHeap.offer(minHeap.poll());
}
}
public double findMedian() {
if (maxHeap.size() > minHeap.size()) {
return maxHeap.peek();
} else {
return (maxHeap.peek() + minHeap.peek()) / 2.0;
}
}
}
复杂度分析:
- 时间复杂度: O(log n)。
- 空间复杂度: 两个堆的总空间为 O(n)。