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

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