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         int n = nums.length;
 9         ArrayList<Integer>[] buckets = new ArrayList[n + 1];
10         for(int i = 0; i <= n; i++){
11             buckets[i] = new ArrayList<Integer>();
12         }
13 
14         for(Map.Entry<Integer, Integer> entry : hm.entrySet()){
15             buckets[entry.getValue()].add(entry.getKey());
16         }
17 
18         int[] res = new int[k];
19         int ind = 0;
20         for(int i = n; i >= 0; i--){
21             for(int num : buckets[i]){
22                 res[ind++] = num;
23                 if(ind == k){
24                     return res;
25                 }
26             }
27         }
28 
29         return res;
30     }
31 }

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 FrequencyTop K Frequent WordsK Closest Points to OriginSort Array by Increasing Frequency.

posted @ 2017-02-03 08:51  Dylan_Java_NYC  阅读(379)  评论(0编辑  收藏  举报