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.
class Solution { public List<Integer> topKFrequent(int[] nums, int k) { Map<Integer, Integer> map = new HashMap<>(); /** count each key frequency */ for(int i = 0; i < nums.length ; i++){ map.put(nums[i], map.getOrDefault(nums[i]) + 1); } /** sort the list */ List<Map.Entry<Integer, Integer>> list = new LinkedList<>(map.entrySet()); Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>(){ /** Sort values in descending order */ public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) { return o2.getValue().compareTo(o1.getValue()); } }); /** find k most frequent element */ List<Integer> res = new ArrayList<>(); for (int i = 0; i< k; i++) res.add((Integer) list.get(i).getKey()); return res; } }
想法一样,无奈不知道如何讲map按value排序
class Solution { public List<Integer> topKFrequent(int[] nums, int k) { List<Integer>[] bucket = new List[nums.length + 1]; Map<Integer, Integer> frequencyMap = new HashMap<Integer, Integer>(); for (int n : nums) { frequencyMap.put(n, frequencyMap.getOrDefault(n, 0) + 1); } for (int key : frequencyMap.keySet()) { int frequency = frequencyMap.get(key); if (bucket[frequency] == null) { bucket[frequency] = new ArrayList<>(); } bucket[frequency].add(key); } List<Integer> res = new ArrayList<>(); for (int pos = bucket.length - 1; pos >= 0 && res.size() < k; pos--) { if (bucket[pos] != null) { res.addAll(bucket[pos]); } } return res; } }
另一种方法是通过桶排序实现
把frequency对应的key存到对应数组位置
然后从后到前把key加入到res中
总结:we know we want the top k frequent elements, this means if we have numbers 1,2,3,4 whose freq are 5,6,7,8, if we want k = 2, we return 4 and 3.
So we first use a hashmap to store elements and their freq,
then we set a bucket whose length is the number of array length + 1, why ? Because we know there are at most array length's numbers , so we can use this bucket to store their frequency
After that, we can iterate from arraylength to 1, in it have top k frequency elements.
Since there's only one and must have one correct answer, we can directly add all bucket's elements to the result.