LeetCode 347. Top K Frequent Elements
原题链接在这里:https://leetcode.com/problems/top-k-frequent-elements/
题目:
Given a non-empty array of integers, return the k most frequent elements.
For example,
Given [1,1,1,2,2,3]
and k = 2, return [1,2]
.
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.
题解:
先计算出element 和对应的frequency.
然后使用bucket sort. 把element按照出现频率放在bucket中.
因为一共只有n 个元素, 那么最大的频率只能是n. n = nums.length. 所以bucket的大小是n+1, 才能对应最大频率.
然后从bucket后扫到前,因为后面的elements 频率高. 加到res中直到res的size到达k.
Note: bucket的生成等号右边是ArrayList[] 而不能是ArrayList<Integer>[], 因为complier 不能判准加进ArrayList中的type, 只有run time才能知道. 所以这里complier不允许确定type.
Time Complexity: O(n), n = nums.length.
Space: O(n).
AC Java:
1 class Solution { 2 public int[] topKFrequent(int[] nums, int k) { 3 HashMap<Integer, Integer> hm = new HashMap<>(); 4 for(int num : nums){ 5 hm.put(num, hm.getOrDefault(num, 0) + 1); 6 } 7 8 ArrayList<Integer>[] buckets = new ArrayList[nums.length + 1]; 9 for(int i = 0; i < buckets.length; i++){ 10 buckets[i] = new ArrayList<Integer>(); 11 } 12 13 for(Map.Entry<Integer, Integer> entry : hm.entrySet()){ 14 int key = entry.getKey(); 15 int freq = entry.getValue(); 16 buckets[freq].add(key); 17 } 18 19 List<Integer> res = new ArrayList<>(); 20 outerloop: 21 for(int i = buckets.length - 1; i >= 0; i--){ 22 for(int can : buckets[i]){ 23 res.add(can); 24 if(res.size() == k){ 25 break outerloop; 26 } 27 } 28 } 29 30 int[] resArr = new int[k]; 31 for(int i = 0; i < k; i++){ 32 resArr[i] = res.get(i); 33 } 34 35 return resArr; 36 } 37 }
AC C++:
1 class Solution { 2 public: 3 vector<int> topKFrequent(vector<int>& nums, int k) { 4 vector<int> res; 5 if(nums.size() == 0 || k <= 0){ 6 return res; 7 } 8 9 unordered_map<int, int> map; 10 for(int num : nums){ 11 map[num]++; 12 } 13 14 vector<vector<int>> buckets(nums.size() + 1); 15 for(auto [k, v] : map){ 16 buckets[v].push_back(k); 17 } 18 19 for(int i = buckets.size() - 1; i >= 0; i--){ 20 for(int can : buckets[i]){ 21 res.push_back(can); 22 if(res.size() == k){ 23 return res; 24 } 25 } 26 } 27 28 return res; 29 } 30 };
AC Python:
1 class Solution: 2 def topKFrequent(self, nums: List[int], k: int) -> List[int]: 3 res = [] 4 n = len(nums) 5 map = Counter(nums) 6 buckets = [[] for _ in range(n + 1)] 7 for key, val in map.items(): 8 buckets[val].append(key) 9 10 for i in range(n, -1, -1): 11 for num in buckets[i]: 12 res.append(num) 13 if len(res) == k: 14 return res 15 16 return res
类似Sort Characters By Frequency, Top K Frequent Words, K Closest Points to Origin, Sort Array by Increasing Frequency.