一开始看到这个题没什么思路,脑袋里都是骚想法,在想有没有什么特殊的技巧做这个题。
最后发现想复杂了,应该用最正常的思路的:
建一个num-count的哈希表,然后排序
又因为这个时间复杂度的需求,所以这里采用堆排序
import java.util.HashMap; import java.util.PriorityQueue; class Solution { public int[] topKFrequent(int[] nums, int k) { HashMap<Integer, Integer> map = new HashMap<>(); for(int i = 0; i<nums.length; i++){ map.put(nums[i],map.getOrDefault(nums[i],0)+1); } PriorityQueue<Integer> heap = new PriorityQueue<>( ((o1, o2) -> map.get(o1) - map.get(o2)) ); for(int num : map.keySet()){ heap.add(num); if(heap.size() > k) heap.poll(); } int [] result = new int[heap.size()]; for (int i = 0; i < result.length; i++) { result[i] = heap.poll(); } return result; } }
- 由于java里有优先队列这个api,就不用手写建立最小堆的过程了
- 优先队列中的lambda函数是对排序规则的定义,这里定义的是升序排列(最小堆)。每次poll出的是最小值。
- 限定大小为k,超过k就poll。这样每次维护一次堆的时间复杂度是logk