leetcode 347. Top K Frequent Elements

朴灿烈づ我的快乐病毒、 2022-06-13 04:55 265阅读 0赞

1.题目

Given a non-empty array of integers, return the k most frequent elements.
一个非空数组,要求返回前K个最频繁出现的元素
For example,
Given [1,1,1,2,2,3] and k = 2, return [1,2].
K一定是有效的,要求时间复杂度小于O(nlogn)
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.

2.分析

1)统计每个元素出现的次数
2)找出出现次数前K个元素
a. 牺牲空间换时间 桶排序
b. 借助数据结构,例如最大堆或最小堆,维护一个大小为k的最小堆或者大小为n-k的最大堆

3.代码

小根堆-priority-queue
priority-queue默认是最大堆,第一个元素是队列中所有元素的最大值。
使用greater函数对象作为比较器可以得到最小堆。
这里需要维护一个大小为k的最小堆。

  1. class Solution {
  2. public:
  3. vector<int> topKFrequent(vector<int>& nums, int k) {
  4. vector<int> ans;
  5. unordered_map<int, int> hashMap;
  6. for (auto x : nums)
  7. ++hashMap[x];
  8. priority_queue<int, vector<int>, greater<int>> min_heap;
  9. for (auto p : hashMap) {
  10. min_heap.push(p.second);
  11. if (min_heap.size() > k)
  12. min_heap.pop();
  13. }
  14. //最终最小堆里保存的是前k的出现次数。第一个元素是出现第k多的次数。
  15. for (auto p : hashMap) {
  16. if (p.second >= min_heap.top())
  17. ans.push_back(p.first);
  18. }
  19. return ans;
  20. }
  21. };

桶排序

  1. class Solution {
  2. public:
  3. vector<int> topKFrequent(vector<int>& nums, int k) {
  4. vector<int> ans;
  5. if (nums.size() < 1)
  6. return ans;
  7. unordered_map<int, int> hashMap;
  8. for (auto x : nums)
  9. ++hashMap[x];
  10. vector<vector<int>> bucket(nums.size() + 1);
  11. for (auto p : hashMap)
  12. bucket[p.second].push_back(p.first);
  13. reverse(bucket.begin(),bucket.end());
  14. for (auto p : bucket) {
  15. for (auto x : p) {
  16. ans.push_back(x);
  17. if (ans.size() == k)
  18. return ans;
  19. }
  20. }
  21. }
  22. };

这个是对出现频次排序,时间复杂度最坏的情况是O(nlogn)

  1. class Solution {
  2. public:
  3. static bool cmpSecond(pair<int, int> a, pair<int, int> b) {
  4. return a.second > b.second;
  5. }
  6. vector<int> topKFrequent(vector<int>& nums, int k) {
  7. vector<int> ans;
  8. if (nums.size() < 1)
  9. return ans;
  10. unordered_map<int, int> hashMap;
  11. for (auto x : nums)
  12. ++hashMap[x];
  13. //按数字出现的频次由大到小排序
  14. vector<pair<int, int>> tmp(hashMap.begin(), hashMap.end());
  15. sort(tmp.begin(), tmp.end(), cmpSecond);
  16. for (int i = 0; i < k; i++)
  17. ans.push_back(tmp[i].first);
  18. return ans;
  19. }
  20. };

发表评论

表情:
评论列表 (有 0 条评论,265人围观)

还没有评论,来说两句吧...

相关阅读