347. 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.
 
注意: 给定的数组是无序的。 有下面两种方法,分别进行介绍。
 
  • 思路1: Bucket sort(map+bucket_sort)
 
Step1: 使用map<int , int >统计每个数在数组中出现的次数。
Step2: 借用桶排序的思想, 申请 sizeof(array)+1 个桶(因为数组中出现频次最多可能就是 sizeof(array)+1) 。 桶是频次n, 桶内存放的是出现频次为n的数组元素 arr1, arr2…arrx。
Step3: 从后往前遍历桶,依次将桶内的元素取出来放到向量里,直到向量的个数为k。
 
 1 class Solution {
 2 public:
 3     vector<int> topKFrequent(vector<int>& nums, int k) {
 4        map<int,int> num_freq;
 5     
 6     //step1
 7     for (int num : nums)
 8         num_freq[num]++;
 9     vector<vector<int>> buckets(nums.size()+1);
10     //step2
11     for (auto bucket: num_freq)
12         buckets[bucket.second].push_back(bucket.first);
13     //step3
14     vector<int> val;
15     for (int i=(int)buckets.size()-1; i>=0 && val.size()<k; i--)
16     {
17         for(auto eachBucket : buckets[i])
18         {
19             val.push_back(eachBucket);
20             if (val.size()>=k)
21                 break;
22         }
23         
24     }
25     return val;
26     }
27 };

 

总结: 空间复杂度:O(n), 时间复杂度:O(n)(n为数组元素的个数)

 
  • 思路2:  Heap Sort

借用priotity queue维持一个最小堆,其中堆的大小为K。 若堆的大小大于K, 则调整出列。

 1 vector<int> topKFrequent(vector<int>& nums, int k) {
 2     priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
 3     
 4     map<int,int> cnt;
 5     for (auto count : nums) cnt[count]++;
 6     
 7     for (auto km : cnt)
 8     {
 9         pq.push({km.second,km.first});
10         if(pq.size()>k)
11             pq.pop();
12     }
13     
14     vector<int> res;
15     while (!pq.empty())
16     {
17         res.push_back(pq.top().second);
18         pq.pop();
19     }
20     return res;
21 }

时间复杂度: O(Nlogk)

上面的堆排序结果是不稳定的,比如 原始向量是 {1,1,1,2,2,3} ,输出的值是{2,1}, 而并不是我们预期的{1, 2}。

若想得到稳定的排序结果,该怎么做呢?

可以使用最大堆,堆的大小为map.size()-k。若超过map.size()-k, 则将堆的最大值放入向量里。

 1 vector<int> topKFrequent(vector<int>& nums, int k) {
 2     map<int,int> counts;
 3     for(int num:nums)
 4         counts[num]++;
 5     
 6     priority_queue<pair<int,int>> pq;
 7     
 8     vector<int> res;
 9     for(auto ct: counts)
10     {
11         pq.push({ct.second, ct.first});
12         if(pq.size()>(counts.size()-k))
13         {
14             res.push_back(pq.top().second);
15             pq.pop();
16         }
17     }
18     return res;
19 }

 

posted @ 2018-01-31 00:42  SuperStar~  阅读(120)  评论(0编辑  收藏  举报