zoukankan      html  css  js  c++  java
  • 【LeetCode-哈希表】前 K 个高频元素

    题目描述

    给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
    示例:

    输入: nums = [1,1,1,2,2,3], k = 2
    输出: [1,2]
    
    输入: nums = [1], k = 1
    输出: [1]
    

    说明:

    • 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
    • 你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
    • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
    • 你可以按任意顺序返回答案。

    题目链接: https://leetcode-cn.com/problems/top-k-frequent-elements/

    思路1

    用哈希表统计每个元素出现的次数,然后根据次数创建一个新的二维数组 v,下标为每个元素出现的次数。例如,v[cnt] = [1,2] 的含义是 1, 2 分别出现了 cnt 次,然后从后往前遍历二维数组 v,如果 v[i] 不空,就将 v[i] 中的元素放进答案中,直到答案中已经包含了 k 个元素。代码如下:

    class Solution {
    public:
        vector<int> topKFrequent(vector<int>& nums, int k) {
            if(nums.empty()) return {};
    
            unordered_map<int, int> hash;
            for(int i=0; i<nums.size(); i++){
                hash[nums[i]]++;
            }
    
            vector<vector<int>> v(nums.size()+1);
            auto it = hash.begin();
            for(; it!=hash.end(); it++){
                int key = it->first;
                int value = it->second;
                v[value].push_back(key);
            }
    
            vector<int> ans;
            for(int i=v.size()-1; i>=0 && ans.size()<k; i--){
                if(!v[i].empty()){
                    for(int j=0; j<v[i].size(); j++) ans.push_back(v[i][j]);
                }
            }
            return ans;
        }
    };
    
    • 时间复杂度:O(n)
    • 空间复杂度:O(n)

    思路2

    思路 2 整体上和思路 1 是一样的,首先用哈希表统计各元素出现的频率,然后使用小根堆来替代思路 1 中的二维数组,可以使用 stl 中的优先队列 priority_queue 来模拟小根堆。小根堆的定义为priority_queue<pair<int, int>> q,pair 的第二个值为元素,第一个值为该元素出现的频率,因为 priority_queue 默认按照 pair 的第一个值降序排序。将优先队列中的元素出队列,并将队头节点pair 的第二个值放进答案中(第二个值就是数组中的元素,第一个值为出现次数)。代码如下:

    class Solution {
    public:
        vector<int> topKFrequent(vector<int>& nums, int k) {
            if(nums.empty()) return {};
    
            unordered_map<int, int> hash;
            for(int i=0; i<nums.size(); i++){
                hash[nums[i]]++;
            }
    
            priority_queue<pair<int, int>> q;
            auto it = hash.begin();
            for(; it!=hash.end(); it++){
                q.push(make_pair(it->second, it->first));
            }
    
            vector<int> ans;
            while(!q.empty() && ans.size()<k){
                auto item = q.top(); q.pop();
                ans.push_back(item.second);
            }
            return ans;
        }
    };
    

    关于按照 pair 中第一个元素升序还是降序排列的问题可以参考这篇文章

    • 时间复杂度:O(nlogk)
    • 空间复杂度:O(n)
  • 相关阅读:
    Django中的CSRF
    CentOS 7上快速安装saltstack
    Django中的Form和ModelForm
    Linux下git使用
    django 登录、注册
    django 知识点小结
    django 博客搭建
    django models中字段
    django models中的class meta
    Django Queryset增加manager
  • 原文地址:https://www.cnblogs.com/flix/p/12940080.html
Copyright © 2011-2022 走看看