题目:Top K Frequent Words
输入一个字符串数组“combo”,输出一个从小到大排列的内容为输入数组出现频率最高的k个词的字符串数组“result”。
比如输入是combo = {"a", "a", "a", "b", "b", "c", "d"}, k = 2, 则输出是{"a", "b"}.
算法时间复杂度: O(n + n * logk + k);
算法空间复杂度: O(n+k)
public class Solution {
static class MyComparator implements Comparator<Map.Entry<String, Integer>> {
public int compare(Map.Entry<String, Integer> a, Map.Entry<String, Integer> b) {
if (a.getValue() == b.getValue()) {
return 0;
} else {
return a.getValue() < b.getValue() ? -1 : 1;
}
}
}
public String[] topKFrequent(String[] combo, int k) {
// Write your solution here
if (combo == null || combo.length == 0 || k <= 0) {
return new String[0];
}
Map<String, Integer> hashmap = new HashMap<>();
Queue<Map.Entry<String, Integer>> minHeap = new PriorityQueue<>(k, new MyComparator());
getMap(combo, hashmap);
for (Map.Entry<String, Integer> curEntry : hashmap.entrySet()) {
if (minHeap.size() < k) {
minHeap.offer(curEntry);
} else {
if (curEntry.getValue() > minHeap.peek().getValue()) {
minHeap.poll();
minHeap.offer(curEntry);
}
}
}
return getTopKFrequentWords(minHeap);
}
public void getMap(String[] combo, Map<String, Integer> hashmap) {
for(String curString : combo) {
if (hashmap.containsKey(curString)) {
hashmap.put(curString, hashmap.get(curString) + 1);
} else {
hashmap.put(curString, 1);
}
}
}
public String[] getTopKFrequentWords(Queue<Map.Entry<String, Integer>> minHeap) {
String[] result = new String[minHeap.size()];
for (int i = result.length - 1; i >= 0; i--) {
result[i] = minHeap.poll().getKey();
}
return result;
}
}
本体所用的算法是最基础的Iteration,用到的数据结构为minHeap和HashMap。
HashMap中的key-value pair为输入中的元素和对应出现的次数。
minHeap中的元素是HashMap中对应的Entry<String, Integer>,需要实现PriorityQueue对应的Comparator接口。
算法的思想很简单,类比选出幼儿园班级中身高最高的k个小朋友,
我们的步骤是,先随便选k个人(真就随便选)。然后每来一个新的小朋友就和已经选好的k个小朋友中个子最矮的进行对比,如果比最矮的高,那就把最矮的踹出去,新的放进来,周而复始,直到小朋友全被过一遍筛子。我们留下的k个就是全班最高的k个小朋友。