原题链接692. 前K个高频单词 - 力扣(LeetCode) (leetcode-cn.com)
思路:
HashMap存放单词和统计次数,打包成entry,创建大小为K的小根堆,找到最大的出现次数最多的k个单词,出队用List接收,最后反转列表。
代码:
class Solution {
public List<String> topKFrequent(String[] words, int k) {
HashMap<String,Integer> map = new HashMap<>();
//统计出现次数
for (String s : words) {
if (map.get(s) == null) {
map.put(s,1);
} else {
Integer val = map.get(s);
map.put(s,val + 1);
}
}
//创建大小为k的小根堆
PriorityQueue<Map.Entry<String,Integer>> minHeap = new PriorityQueue<>(k,new Comparator<Map.Entry<String,Integer>>(){
public int compare(Map.Entry<String,Integer> o1,Map.Entry<String,Integer> o2) {
//因为是小根堆,题目要求从大到小排序,所以后面要反转,改变字母排序规则
if (o1.getValue().compareTo(o2.getValue()) == 0) {
return o2.getKey().compareTo(o1.getKey());
}
return o1.getValue() - o2.getValue();
}
});
for (Map.Entry<String,Integer> entry : map.entrySet()) {
if (minHeap.size() < k) {
minHeap.offer(entry);
} else {
Map.Entry<String,Integer> top = minHeap.peek();
//如果key值相等,按字母排序
if (top.getValue().compareTo(entry.getValue()) == 0) {
if (top.getKey().compareTo(entry.getKey()) > 0) {
minHeap.poll();
minHeap.offer(entry);
}
} else {
//key值不相等,按照出现次数value排序
if (top.getValue().compareTo(entry.getValue()) < 0) {
minHeap.poll();
minHeap.offer(entry);
}
}
}
}
//定义列表接收小根堆的key值(注意不是Value值,Value代表的是key出现的次数)
List<String> list = new ArrayList<>();
//注意这里k不能改成minHeap。size(),因为minHeap在poll的时候size会变化
for (int i = 0;i < k;i++) {
Map.Entry<String,Integer> entry = minHeap.poll();
list.add(entry.getKey());
}
//最后根据题目要求从大到小排序反转列表
Collections.reverse(list);
return list;
}
}