Given a non-empty array of integers, return the k most frequent elements.
Example 1:
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]
Example 2:
Input: nums = [1], k = 1
Output: [1]
Note:
- You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
- Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
M1: use maxHeap. Put entry into maxHeap so we can always poll a number with the largest frequency
time: O(nlogn) -- O(n) for traverse, O(logn) for adding elements in heap, space: O(n)
class Solution { public List<Integer> topKFrequent(int[] nums, int k) { HashMap<Integer, Integer> map = new HashMap<>(); for(int n : nums) { map.put(n, map.getOrDefault(n, 0) + 1); } PriorityQueue<Map.Entry<Integer, Integer>> maxHeap = new PriorityQueue<>((a, b) -> b.getValue() - a.getValue()); for(Map.Entry<Integer, Integer> entry: map.entrySet()) { maxHeap.add(entry); } List<Integer> res = new ArrayList<>(); while(res.size() < k) { res.add(maxHeap.poll().getKey()); } return res; } }
M2: use treeMap documents
treemap基于红黑树,检索时间是O(logn),默认按照key的自然大小排序(升序,从小到大)
Use frequency as the key so we can get all frequencies in order,先用hashmap统计频率,再放入treemap <freq, n>,最后取出前k个value即可
time: O(nlogn), space: O(n)
class Solution { public List<Integer> topKFrequent(int[] nums, int k) { Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for(int n : nums) { map.put(n, map.getOrDefault(n, 0) + 1); } TreeMap<Integer, List<Integer>> treemap = new TreeMap<>(); for(Map.Entry<Integer, Integer> entry : map.entrySet()) { int num = entry.getKey(), freq = entry.getValue(); if(!treemap.containsKey(freq)) { treemap.put(freq, new ArrayList<>()); } treemap.get(freq).add(num); } List<Integer> res = new ArrayList<>(); while(res.size() < k) { List<Integer> list = treemap.pollLastEntry().getValue(); for(int i = 0; i < list.size(); i++) { if(res.size() < k) res.add(list.get(i)); else break; } } return res; } }