[抄题]:
给一个单词列表,求出这个列表中出现频次最高的K个单词。
[思维问题]:
- 以为已经放进pq里就不能改了。其实可以改,利用每次取出的都是顶上的最小值就行了。(性质)
- 不知道怎么处理k个之外的数:先把peak, newpair拿出来
[一句话思路]:
[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):
[画图]:
[一刷]:
- 比较之前要新建对象。right.key.compareTo(left.key)是反的,而且需要单独写出来,因为比较的是key是否相同
- for (String word : words),word的作用类似于i,作为临时变量来使用
- 取出所有的key,用的是counter.keySet()
- 用comparator的compare方法来比较
- Q.poll().key表示取出头元素
[二刷]:
- comparator是自己定义的,除了heap中,别的地方不能用,加关键字private
- pq里装的是pair, 不是string
- pair类中的函数是public pair,不是int
[三刷]:
- peak, newpair要先取出来,因为不足k时添加的也是newpair
[四刷]:
[五刷]:
[总结]:
[复杂度]:Time complexity: O(nlgk) Space complexity: O(n)
[英文数据结构,为什么不用别的数据结构]:
pq 每次取出最小值,不用删除下面的元素 所以不用tree
[其他解法]:
[Follow Up]:
[LC给出的题目变变变]:
347. Top K Frequent Elements,一模一样的:除了pair里的东西不一样
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution { class Pair { String key; int value; public Pair(String key,int value) { this.key = key; this.value = value; } }; private Comparator<Pair> pairComparator = new Comparator<Pair>() { public int compare(Pair left,Pair right) { if (left.value != right.value) { return left.value - right.value; } return right.key.compareTo(left.key); } }; public List<String> topKFrequent(String[] words, int k) { //HashMap if (k == 0) { return null; } HashMap<String,Integer> counter = new HashMap<String,Integer>(); for (String word : words) { if (counter.containsKey(word)) { counter.put(word,counter.get(word) + 1); } else if (!counter.containsKey(word)) { counter.put(word,1); } } //minHeap Queue<Pair> Q = new PriorityQueue<Pair>(k,pairComparator); for (String word : counter.keySet()) { Pair peak = Q.peek(); Pair newPair = new Pair(word,counter.get(word)); if (Q.size() < k) { Q.add(newPair); } else if (pairComparator.compare(newPair,peak) > 0) { Q.poll(); Q.add(newPair); } } //result List<String> result = new ArrayList<String>(); while (!Q.isEmpty()) { result.add(0,Q.poll().key); } return result; } }