题目描述:

核心思想:
先利用哈希表统计各个元素的频率,再利用小顶堆堆顶元素即是最小元素的特性,维护一个前k个高频元素的数据集。
代码思路:
-
统计频率
首先,使用一个哈希表(
HashMap)来统计数组中每个数字出现的次数。遍历数组,对于每个数字,如果它已经在哈希表中,就将其对应的计数加1;如果不在,就将其加入哈希表并初始化计数为1。这样可以快速统计出每个数字的出现频率。 -
维护最小堆
使用一个最小堆(优先队列)来维护当前出现频率最高的
k个数字。最小堆的大小始终保持为k,并且堆顶元素是频率最小的数字。遍历哈希表中的所有数字:
-
如果当前最小堆的大小小于
k,直接将该数字加入堆中。 -
如果最小堆的大小已经等于
k,并且当前数字的频率大于堆顶元素的频率,则移除堆顶元素,并将当前数字加入堆中。这样可以保证堆中始终存储的是当前频率最高的k个数字。
-
-
提取结果
将最小堆中的所有数字依次取出,存入一个列表中。由于最小堆是按照频率从小到大排序的,最终需要将列表中的数字反转,以得到频率从高到低的结果。最后,将列表转换为数组,返回结果。
代码:
java
class Solution {
public int[] topKFrequent(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
if (map.containsKey(num)) {
map.put(num, map.get(num) + 1);
} else {
map.put(num, 1);
}
}
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> map.get(a) - map.get(b));
for (Integer key : map.keySet()) {
if (pq.size() < k) {
pq.add(key);
} else if (map.get(pq.peek()) < map.get(key)) {
pq.remove();
pq.add(key);
}
}
List<Integer> list = new ArrayList<>();
while (!pq.isEmpty()) {
list.add(pq.remove());
}
int[] res=list.stream().mapToInt(Integer::intValue).toArray();
return res;
}
}