https://leetcode-cn.com/problems/top-k-frequent-elements/
小根堆实现
leetcode的测试数据估计是因为不全是N远大于K的数据,导致用小跟堆反而比大根堆或TreeMap慢……因为当N不大时,每次删除最小元素都要多出2logK次比较,而且小根堆最后还要反转;
public class Solution {
public List<Integer> topKFrequent(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int val: nums) {
map.put(val, map.getOrDefault(val, 0) + 1);
}
//使用Map.Entry来存储最直接,有getKey和getValue可以直接用
PriorityQueue<Map.Entry<Integer, Integer>> pq = new PriorityQueue<>((a, b) -> (a.getValue() - b.getValue()));
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
pq.add(entry);
if(pq.size()> k)
pq.poll();
}
List<Integer> result = new ArrayList<>();
for (int i = 0; i < k; i++)
result.add(pq.poll().getKey());
Collections.reverse(result);
return result;
}
}
TreeMap实现
public class Solution {
public List<Integer> topKFrequent(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int val: nums) {
map.put(val, map.getOrDefault(val, 0) + 1);
}
TreeMap<Integer, List<Integer>> treeMap = new TreeMap<>();
for (key in map.keySet()){
int value = map.get(key);
if(!treeMap.containsKey(value))
treeMap.put(value, new ArrayList<Integer>());
treeMap.get(value).add(key);
}
List<Integer> result = new ArrayList<>();
//TreeMap一次是添加一个数组,不能像堆一样for k次
while(result.size()<k)
result.addAll(treeMap.pollLastEntry().getValue());
return result;
}
}
map用法总结
map.get();
map.keySet();
map.entrySet();
entry.getKey();
entry.getValue();
堆是通过(a, b) -> (a.getValue() - b.getValue())实现用value排序,所以最后通过entry.getKey()获得topK的Key;
TreeMap通过 treeMap.put(value, new ArrayList<>()) 与 treeMap.get(value).add()来实现用value排序,所以最后treeMap.getValue获得ArrayList,addAll()全部加入到result。