给一个单词列表,求出这个列表中出现频次最高的K个单词。
样例
给出单词列表:
[
"yes", "lint", "code",
"yes", "code", "baby",
"you", "baby", "chrome",
"safari", "lint", "code",
"body", "lint", "code"
]
如果 k = 3
, 返回 ["code", "lint", "baby"]
。
如果 k = 4
, 返回 ["code", "lint", "baby", "yes"]
。
挑战
用 O(n log k)的时间和 O(n) 的额外空间完成。
解题思路:
先用哈希表统计出每个单词的频次,然后将单词与频次信息组合成对象放入TreeSet中,其中TreeSet需要自定义排序,先按照频次降序,然后按照字典序升序。最后将TreeSet中前K个元素取出来即可。
public class Solution {
/**
* @param words: an array of string
* @param k: An integer
* @return: an array of string
*/
public String[] topKFrequentWords(String[] words, int k) {
// write your code here
Map<String , Integer> map = new HashMap<>();
for(String s : words){
if(map.get(s) == null)
map.put(s, 1);
else
map.put(s, map.get(s) + 1);
}
TreeSet<Pair> set = new TreeSet<>(new Comparator<Pair>(){
@Override
public int compare(Pair a, Pair b){
//按频次降序
if(a.times != b.times)
return b.times - a.times;
//按字典升序
return a.str.compareTo(b.str);
}
});
for(String s : map.keySet())
set.add(new Pair(s, map.get(s)));
String[] res = new String[k];
for(int j=0; j<k && !set.isEmpty(); j++)
res[j] = set.pollFirst().str;
return res;
}
class Pair{
public String str;
public int times;
public Pair(String str, int times){
this.str = str;
this.times = times;
}
}
}