Top K Frequent Words
Given
[
"yes", "lint", "code",
"yes", "code", "baby",
"you", "baby", "chrome",
"safari", "lint", "code",
"body", "lint", "code"
]Given
[
"yes", "lint", "code",
"yes", "code", "baby",
"you", "baby", "chrome",
"safari", "lint", "code",
"body", "lint", "code"
] public class Solution {
public String[] topKFrequent(String[] combo, int k) {
Map<String, Integer> map = new HashMap<>();
for (String s : combo) {
map.put(s, map.getOrDefault(s, 0) + 1);
}
String[] buckets = new String[combo.length + 1];
Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Integer> entry = it.next();
buckets[entry.getValue()] = entry.getKey();
}
List<String> res = new ArrayList<>();
for (int i = buckets.length - 1; i > 0; --i) {
if (res.size() < k && buckets[i] != null) {
res.add(buckets[i]);
}
}
return res.toArray(new String[res.size()]);
}
} class Solution:
"""
@param: words: an array of string
@param: k: An integer
@return: an array of string
"""
def topKFrequentWords(self, words, k):
counter = collections.defaultdict(int)
for word in words:
counter[word] += 1
# 获取bucket范围
minFreq, maxFreq = float('INF'), float('-INF')
for word in counter:
minFreq = min(minFreq, counter[word])
maxFreq = max(maxFreq, counter[word])
# 把words存入buckets
buckets = [None] * (maxFreq - minFreq + 1)
for word in counter:
index = counter[word] - minFreq
if buckets[index] is None:
buckets[index] = set()
buckets[index].add(word)
# 从右向左,拿k个words,最后一个bucket可能需要排序
res = []
for i in range(len(buckets) - 1, -1, -1):
if buckets[i] is None: continue
# 关键,对每组相同词频的words,按字母顺序进行排序再extend到res
temp = list(buckets[i])
temp.sort()
res.extend(temp)
if len(res) > k:
break
# 截取k个返回
return res[:k] public class Solution {
/*
* @param words: an array of string
* @param k: An integer
* @return: an array of string
*/
private class QElement {
int freq;
String word;
public QElement(String word, int freq) {
this.word = word;
this.freq = freq;
}
}
public String[] topKFrequentWords(String[] words, int k) {
if (k == 0) return new String[0];
// 统计词频
Map<String, QElement> counter = new HashMap<>();
for (String word : words) {
if (! counter.containsKey(word)) {
counter.put(word, new QElement(word, 0));
}
counter.get(word).freq++;
}
// 存入pq
PriorityQueue<QElement> pq = new PriorityQueue<>(k, new Comparator<QElement>(){
// 1st key 表示是对于freq的min heap
// 2st key 则表示是对于string字母顺序的max heap(维持字母顺序最小的word的集合)
@Override
public int compare(QElement e1, QElement e2) {
if (e1.freq != e2.freq) return e1.freq - e2.freq;
return e2.word.compareTo(e1.word);
}
});
for (String word : counter.keySet()) {
pq.offer(counter.get(word));
if (pq.size() > k) pq.poll();
}
// pq中已经是k个频率最大的,poll出来返回
String[] res = new String[k];
for (int i = 0; i < k; ++i) {
res[k - i - 1] = pq.poll().word;
}
return res;
}
}class Solution {
private class Node implements Comparable<Node> {
String str;
int num;
public Node(String str, int num) {
this.str = str;
this.num = num;
}
@Override
public int compareTo(Node that) {
if (this.num != that.num) {
return Integer.compare(this.num, that.num);
} else {
return that.str.compareTo(this.str);
}
}
}
public List<String> topKFrequent(String[] words, int k) {
Map<String, Integer> counter = new HashMap<>();
PriorityQueue<Node> pq = new PriorityQueue<>();
List<String> res = new ArrayList<>();
for (String str : words) {
counter.put(str, counter.getOrDefault(str, 0) + 1);
}
for (Map.Entry<String, Integer> entry : counter.entrySet()) {
Node currNode = new Node(entry.getKey(), entry.getValue());
pq.add(currNode);
if (pq.size() > k) pq.poll();
}
while (pq.size() > 0) {
res.add(pq.poll().str);
}
Collections.reverse(res);
return res;
}
}