给一非空的单词列表,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。
示例 1:
示例 2:
注意:
- 假定 k 总为有效值, 1 ≤ k ≤ 集合元素数。
- 输入的单词均由小写字母组成。
扩展练习:尝试以 O(n log k) 时间复杂度和 O(n) 空间复杂度解决.
(1)There is a pretty simple Brute Force solution - create a map (word->occurance), then put EntrySet
to List
and sort this list with a custom comparator. The time complexity is O(N log N)
.
(2)But since we need to return k
popular items only - we don't need to sort all items. So, the second idea is to use Heap
with limited capacity k
. The time complexity is O(N log K)
(3)The third solution is to use Bucket Sort - O(N + K log K)
(1)
Map<String, Integer> count = new HashMap();
for (String word: words) {
count.put(word, count.getOrDefault(word, 0) + 1);
}
List<String> candidates = new ArrayList(count.keySet());
Collections.sort(candidates, (w1, w2) -> count.get(w1).equals(count.get(w2)) ?
w1.compareTo(w2) : count.get(w2) - count.get(w1));
return candidates.subList(0, k);
(2)
Map<String, Integer> map = new HashMap<>();
for(String w : words) map.put(w, map.getOrDefault(w, 0)+1);
PriorityQueue<Map.Entry<String, Integer>> pq = new PriorityQueue<>((e1, e2)->{
int res = e1.getValue() - e2.getValue();
if(res==0) return e2.getKey().compareTo(e1.getKey());
return res;
});
for(Map.Entry e : map.entrySet()) {
pq.add(e);
if (pq.size() > k) pq.poll();
}
List<String> res = new ArrayList<>();
for(int i=0;i<k;i++) res.add(pq.poll().getKey());
Collections.reverse(res);
return res;
(3)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);
List<String>[] buckets = new List[words.length+1];
for(String key:map.keySet()){
int freq = map.get(key);
if(buckets[freq]==null)
buckets[freq] = new LinkedList<>();
buckets[freq].add(key);
}
List<String> ans = new LinkedList<>();
int c = 0;
for(int i = buckets.length-1;i>=0&&k>0;i--){
if(buckets[i]!=null){
Collections.sort(buckets[i]);
for(int j=0;j<buckets[i].size();j++) {
if(c==k)
return ans;
ans.add(buckets[i].get(j));
c++;
}
}
}
return ans ;
}