AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 应用
  • 更多
    • 题解
    • 分享
    • 商店
    • 问答
    • 吐槽
  • App
  • 登录/注册

LeetCode 347. Top K Frequent Elements    原题链接    中等

作者: 作者的头像   yxc ,  2018-06-28 22:45:17 ,  所有人可见 ,  阅读 2889


3


3

题目描述

给定一个非空整数数组,请返回出现次数最多的 $k$ 个数。

注意:

  • 你可以假定 $k$ 一定是合法的,即 $1 \le k \le$ 数组中不同元素的个数,且排名在第 $k$ 位和排名在第 $k+1$ 位的数,出现次数不同;
  • 你的算法一定要比 $O(nlogn)$ 快;

样例

给定 [1,1,1,2,2,3] 并且 k = 2,
返回 [1,2].

算法

(哈希表,计数排序) $O(n)$

首先用哈希表统计出所有数出现的次数。
由于所有数出现的次数都在 $1$ 到 $n$ 之间,所以我们可以用计数排序的思想,统计出次数最多的前 $k$ 个元素的下界。然后将所有出现次数大于等于下界的数输出。

时间复杂度分析:用哈希表统计每个数出现次数的计算量是 $O(n)$,计数排序的计算量是 $O(n)$,最终用下界过滤结果的计算量也是 $O(n)$,所以总时间复杂度是 $O(n)$。

C++ 代码

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int> hash;
        vector<int> res;
        for (int x : nums) hash[x] ++;
        int n = nums.size();
        vector<int>s(n + 1, 0);
        for (auto &p : hash) s[p.second] ++ ;
        int i = n, t = 0;
        while (t < k) t += s[i -- ];
        for (auto &p : hash)
            if (p.second > i)
                res.push_back(p.first);
        return res;
    }
};

9 评论


用户头像
xju_wzp   2个月前      1    踩      回复
class Solution {
public:
    static bool comp(const pair<int,int> &a, const pair<int,int> &b) {
            return a.second > b.second;
        }
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int> umap;
        for (auto c : nums) umap[c]++;
        vector<pair<int,int>> b;
        for (auto x : umap) b.push_back(x);
        sort(b.begin(),b.end(),comp);
        vector<int> res;
        for (int i = 0; i < k; i++) res.push_back(b[i].first);
        return res;
    }
};

用户头像
st   2019-03-19 07:21         踩      回复

如果要求返回值一定按照freq输出的话 除了map+pq有没有别的做法啊?每次写pq的cmp都会写错,想知道能不能绕过自定义这些东西……

用户头像
yxc   2019-03-19 14:46         踩      回复

在用priority_queue的时候,可以用STL里的pair[HTML_REMOVED],它默认以first为第一关键字,以second为第二关键字比较大小。

用户头像
st   2019-03-19 23:58    回复了 yxc 的评论         踩      回复

nice!


用户头像
st   2019-03-19 07:07         踩      回复

如果要求返回值一定要按照frequency输出的话 还能用计数排序做吗?

用户头像
yxc   2019-03-19 14:44         踩      回复

可以的,计数排序可以将所有数排好序。

用户头像
st   2019-03-20 00:00    回复了 yxc 的评论         踩      回复

为啥呢?这里不是找到前n个的阈值然后扫一遍hashmap输出阈值之上的?为什么是有序的呢?

用户头像
yxc   2019-03-20 04:36    回复了 st 的评论         踩      回复

可以参考一下这篇文章 计数排序详解


用户头像
海   2019-01-15 20:36         踩      回复

(๑•̀ㅂ•́)و✧


你确定删除吗?
1024
x

© 2018-2023 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息