zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    mac os x 查看网络端口情况
    mac 启动php-fpm报错 failed to open configuration file '/private/etc/php-fpm.conf': No such file or direc
    视频播放—— H5同层播放器接入规范
    [转]webpack中require和import的区别
    职场方法论系列—怎样做项目
    一幅图帮你搞懂订单的拆分与合并
    如何用数据去驱动决策?
    分库分表的 9种分布式主键ID 生成方案,挺全乎的
    快手基于 Apache Flink 的优化实践
    SQL数据库中临时表、临时变量和WITH AS关键词创建“临时表”的区别
  • 原文地址:https://www.cnblogs.com/zhaoyaxing/p/8388202.html
Copyright © 2011-2022 走看看