开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 28 天,点击查看活动详情
LeetCode692:前K个高频单词
给定一个单词列表 words 和一个整数 k ,返回前 k **个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。
示例 1:
输入: words = ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。
注意,按字母顺序 "i" 在 "love" 之前。
示例 2:
输入: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4
输出: ["the", "is", "sunny", "day"]
解析: "the", "is", "sunny" 和 "day" 是出现次数最多的四个单词,
出现次数依次为 4, 3, 2 和 1 次。
注意:
1 <= words.length <= 5001 <= words[i] <= 10words[i]由小写英文字母组成。k的取值范围是[1, 不同 words[i] 的数量]
思路分析
由题意可分析知按单词出现频率由高到低排序,如果不同的单词有相同出现频率,按字母顺序排序。
- 1、使用HashMap统计单词的频次
- 2、维护一个元素数量是k的小根堆,遍历哈希表将单词与对应的频次不断插入小根堆中,小根堆的排序规则是先按count升序排序,count相同的按word字典序降序排序。当小根堆的元素多于k个时就把堆顶的元素删除。
- 3、最后小根堆里剩下的k个元素就是要求的结果
算法代码
class Node {
String word;
int count;
public Node(String word, int count) {
this.word = word;
this.count = count;
}
}
public List < String > topKFrequent(String[] words, int k) {
HashMap < String, Integer > countMap = new HashMap < > ();
for (String word: words) {
countMap.put(word, countMap.getOrDefault(word, 0) + 1);
}
PriorityQueue < Node > priorityQueue = new PriorityQueue < > (k, new Comparator < Node > () {@
Override
public int compare(Node o1, Node o2) {
//先按count升序排序,count相同的按字典序降序排序
int x = o1.count - o2.count;
if (x == 0) {
return o2.word.compareTo(o1.word);
}
return x;
}
});
for (String word: countMap.keySet()) {
int count = countMap.get(word);
priorityQueue.add(new Node(word, count));
if (priorityQueue.size() > k) {
priorityQueue.remove();
}
}
LinkedList < String > res = new LinkedList < > ();
while (!priorityQueue.isEmpty()) {
res.addFirst(priorityQueue.remove().word);
}
return res;
}
结果详情
算法复杂度
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN)一起进步,一起成长!