赞
踩
题目要求:
分析:
这种题目又来了,根深蒂固的HashMap思想绝对是呼之欲出。于是不假思索,先用HashMap求出每个数字有几个再说。
求出每个数字的频率之后,我们想要求出第k高的频率的元素,并且时间复杂度必须优于O(nlog n),那么该如何求呢?
我们应该想到,堆的时间复杂度正好是O(nlog n),可以用堆来求。而堆是可以利用优先队列PriorityQueue来求的。
我们想要求出第k个频率的数字,那么肯定要堆这些数字出现的次数进行排列,那么优先队列正好是最合适的求法,我们可以让它最先pop出来的是最大值,至于这个排序方法,就是利用匿名内部类,把compare方法给重写一下,这个方法已经用过多次了。
然后就可以取出map中的key值与优先队列中的peek值进行比较了,如果队列没满(队列的容量为k),则将他们加入进来,如果队列满了,并且现在遍历到的这个值大于队列中的peek值,就把队列中最小的给remove掉,然后把这个值给add进去。
最后只要把优先队列中的值给弹出,然后再add到list中去就可以了。
具体代码如下:
class Solution { public List<Integer> topKFrequent(int[] nums, int k) { if(nums == null || nums.length == 0) return new ArrayList<>(); Map<Integer, Integer> map = new HashMap<>(); for(int num : nums) { if(!map.containsKey(num)) { map.put(num, 1); } else { map.put(num, map.get(num) + 1); } } // 遍历map,用最小堆保存频率最大的k个元素 PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() { @Override public int compare(Integer a, Integer b) { return map.get(a) - map.get(b); } }); //将Map中所有的键存入到set集合中 for (Integer key : map.keySet()) { if (pq.size() < k) { pq.add(key); } else if (map.get(key) > map.get(pq.peek())) { pq.remove(); pq.add(key); } } // 取出最小堆中的元素 List<Integer> list = new ArrayList<>(); while (!pq.isEmpty()) { list.add(pq.remove()); } return list; } }
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。