一、题目
给一非空的单词列表,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。
二、思路
1、哈希+优先队列
根据题意,首先需要记录每个单词出现的次数,然后根据出现的频率和字母顺序排序,取前k个即可。这么一说感觉有点复杂,拆解步骤一下:
1)记录每个单词出现次数
用一个哈希表,键为字符串,值为出现次数记录
2)优先队列进行排序
(使用链表进行排序也行,但为了减小时间复杂度使用优先队列)
建立优先队列,直接使用Map.Entry
1、如果出现次数不等,出现次数小的在顶部 2、如果出现次数相等,使用String的compareTo进行对比
三、代码
1、哈希+优先队列
class Solution {
public List<String> topKFrequent(String[] words, int k) {
Map<String, Integer> map = new HashMap<>();
for (String word : words) {
map.put(word, map.getOrDefault(word, 0) + 1);
}
Queue<Map.Entry<String, Integer>> q = new PriorityQueue<>(k, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
if (e1.getValue() == e2.getValue()) {
return e2.getKey().compareTo(e1.getKey());
}
return e1.getValue() - e2.getValue();
}
});
for (Map.Entry<String, Integer> entry : map.entrySet()) {
q.add(entry);
if (q.size() > k) {
q.poll();
}
}
List<String> ans = new ArrayList();
while (q.size() != 0) {
ans.add(q.poll().getKey());
}
Collections.reverse(ans);
return ans;
}
}
n为words中元素个数,时间复杂度为O(n+n*logk+k),空间复杂度为O(n+k)。