题目
给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。
- 来源:力扣(LeetCode)
- 链接:leetcode.cn/problems/to…
- 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法一
思路
- Map统计
- 最小堆获取topk
代码一
public static List<String> topKFrequent(String[] words, int k) {
Map<String, Integer> map = new HashMap<>();
for (String word : words) {
Integer count = map.get(word);
if (count == null) {
map.put(word, 1);
} else {
map.put(word, ++count);
}
}
Queue<Word> queue = new PriorityQueue<>();
for (Map.Entry<String, Integer> entry : map.entrySet()) {
Word word = new Word(entry.getKey(), entry.getValue());
queue.offer(word);
if (queue.size() > k) {
queue.poll();
}
}
List<String> list = new LinkedList<>();
while (!queue.isEmpty()) {
list.add(queue.poll().word);
}
Collections.reverse(list);
return list;
}
private static class Word implements Comparable<Word> {
private String word;
private int count;
public Word(String word, int count) {
this.word = word;
this.count = count;
}
public int compareTo(Word that) {
return this.count == that.count ? that.word.compareTo(this.word) : this.count - that.count;
}
}
复杂度
- 时间复杂度:O(nlogn)
- 空间复杂度:O(n)
- 上面的代码击败79%
代码二
最后输出的时候,需要反转。可以使用Deque。
public static List<String> topKFrequent(String[] words, int k) {
Map<String, Integer> map = new HashMap<>();
for (String word : words) {
Integer count = map.get(word);
if (count == null) {
map.put(word, 1);
} else {
map.put(word, ++count);
}
}
Queue<Word> queue = new PriorityQueue<>();
for (Map.Entry<String, Integer> entry : map.entrySet()) {
Word word = new Word(entry.getKey(), entry.getValue());
queue.offer(word);
if (queue.size() > k) {
queue.poll();
}
}
Deque<String> deque = new LinkedList<>();
while (!queue.isEmpty()) {
deque.offerFirst(queue.poll().word);
}
return new LinkedList<>(deque);
}
private static class Word implements Comparable<Word> {
private String word;
private int count;
public Word(String word, int count) {
this.word = word;
this.count = count;
}
public int compareTo(Word that) {
return this.count == that.count ? that.word.compareTo(this.word) : this.count - that.count;
}
}
上面的代码击败了99.5%。