leetcode-347:前 K 个高频元素

简介: leetcode-347:前 K 个高频元素

题目

题目链接

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

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

示例 2:

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

解答

方法一:优先队列

主要就分为以下几个步骤

  1. 要统计元素出现频率
  2. 对频率排序
  3. 找出前K个高频元素

python写法

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        hush = {}
        for num in nums:
            hush[num] = hush.get(num,0)+1
        heap = []
        for key,freq in hush.items():
            heapq.heappush(heap,(freq,key))
            if len(heap)>k:
                heapq.heappop(heap)
        res = []
        for _ in range(k):
            res.append(heapq.heappop(heap)[1])
        return res

c++写法

现代C++之理解decltype

C++11 auto和decltype关键字

c++优先队列(priority_queue)用法详解

priority_queue的用法

347.前 K 个高频元素

我们要用小顶堆,因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素

class Solution {
public:
    class mycomparsion{
    public:
        bool operator()(const pair<int,int>& lhs,const pair<int,int>&rhs){
            return lhs.second>rhs.second;
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int> map;
        for(int num:nums){
            map[num]++;
        }
        priority_queue<pair<int,int>,vector<pair<int,int>>,mycomparsion> pri_que;
        for(unordered_map<int,int>::iterator it=map.begin();it!=map.end();it++){
            pri_que.push(*it);
            if(pri_que.size()>k){
                pri_que.pop();
            }
        }
        vector<int> res(k);
        for(int i=k-1;i>=0;i--){
            res[i]=pri_que.top().first;
            pri_que.pop();
        }
        return res;
    }
};

修改了一下map遍历方式

// 小顶堆
class Solution {
public:
    class mycomparsion{
    public:
        bool operator()(const pair<int,int>& lhs,const pair<int,int>&rhs){
            return lhs.second>rhs.second;
        }
    };
    // 要统计元素出现频率
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int> map;
        for(int num:nums){
            map[num]++;
        }
    // 对频率排序
        // 定义一个小顶堆,大小为k
        priority_queue<pair<int,int>,vector<pair<int,int>>,mycomparsion> pri_que;
        for(pair<int,int> it:map){ 
            pri_que.push(it);
            if(pri_que.size()>k){ // 如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k
                pri_que.pop();
            }
        }
    // 找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒叙来输出到数组
        vector<int> res(k);
        for(int i=k-1;i>=0;i--){
            res[i]=pri_que.top().first;
            pri_que.pop();
        }
        return res;
    }
};

另外一种写法

class Solution {
public:
    bool static cmp(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> map;
        for(int num:nums){
            map[num]++;
        }
        priority_queue<pair<int,int>,vector<pair<int,int>>,decltype(&cmp)> pri_queue(cmp);
        for(pair<int,int> it:map){
            pri_queue.push(it);
            if(pri_queue.size()>k){
                pri_queue.pop();
            }
        }
        vector<int> res(k);
        for(int i=k-1;i>=0;i--){
            res[i]=pri_queue.top().first;
            pri_queue.pop();
        }
        return res;
    }
};

2022/3/2

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int> map;
        for(int num:nums){
            map[num]++;
        }
        struct cmp{
            bool operator()(pair<int,int>& a,pair<int,int>& b)const{
                return a.second<b.second;
            }
        };
        priority_queue<pair<int,int>,vector<pair<int,int>>,cmp> q;
        for(const pair<int,int>& p:map){
            q.push(p);
        }
        vector<int> res;
        for(int i=0;i<k;i++){
            res.push_back(q.top().first);
            q.pop();
        }
        return res;
    }
};

java

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer,Integer> mp=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            mp.put(nums[i],mp.getOrDefault(nums[i],0)+1);
        }
        PriorityQueue<Integer> pq=new PriorityQueue<>(new Comparator<Integer>(){
            @Override
            public int compare(Integer a,Integer b){
                // if(mp.get(a)>mp.get(b)) return 1;
                // else return 0;
                if(mp.get(a)>mp.get(b)) return 1;
                else return -1;
            }
        });
        for(Integer key:mp.keySet()){
            if(pq.size()<k){
                pq.add(key);
            }else if(mp.get(key)>mp.get(pq.peek())){
                pq.remove();
                pq.add(key);
            }
        }
        int res[]=new int[pq.size()];
        int i=0;
        while(!pq.isEmpty()){
            res[i++]=pq.remove();
        }
        return res;
    }
}

方法二:排序+暴力

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int> map;
        for(int num:nums){
            map[num]++;
        }
        vector<pair<int,int>> vec(map.begin(),map.end());
        sort(vec.begin(),vec.end(),[](pair<int,int>&a,pair<int,int>&b){return a.second>b.second;});
        vector<int> res;
        for(int i=0;i<k;i++){
            res.push_back(vec[i].first);
        }
        return res;
    }
};


相关文章
|
3月前
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
42 1
|
3月前
【LeetCode 27】347.前k个高频元素
【LeetCode 27】347.前k个高频元素
42 0
|
3月前
【LeetCode 06】203.移除链表元素
【LeetCode 06】203.移除链表元素
35 0
|
3月前
【LeetCode-每日一题】移除元素
【LeetCode-每日一题】移除元素
36 0
|
5月前
|
存储 算法
LeetCode第83题删除排序链表中的重复元素
文章介绍了LeetCode第83题"删除排序链表中的重复元素"的解法,使用双指针技术在原链表上原地删除重复元素,提供了一种时间和空间效率都较高的解决方案。
LeetCode第83题删除排序链表中的重复元素
|
5月前
|
算法 索引
LeetCode第34题在排序数组中查找元素的第一个和最后一个位置
这篇文章介绍了LeetCode第34题"在排序数组中查找元素的第一个和最后一个位置"的解题方法,通过使用双指针法从数组两端向中间同时查找目标值,有效地找到了目标值的首次和最后一次出现的索引位置。
LeetCode第34题在排序数组中查找元素的第一个和最后一个位置
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer II 082. 含有重复元素集合的组合
解决LeetCode平台《剑指 Offer II 082. 含有重复元素集合的组合》题目的Python代码实现,通过深度优先搜索算法找出所有和为特定目标值的数字组合,并在搜索过程中通过排序和跳过重复元素来避免解集中出现重复组合。
44 2
|
5月前
|
算法
LeetCode第27题移除元素
这篇文章介绍了LeetCode第27题"移除元素"的解题方法,通过使用双指针技巧,有效移除数组中特定值的元素并返回新数组的长度。
|
5月前
|
算法 索引 Python
【Leetcode刷题Python】34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)
解决LeetCode "在排序数组中查找元素的第一个和最后一个位置" 问题的方法。第一种方法是使用两次二分查找,首先找到目标值的最左边界,然后找到最右边界。第二种方法是利用Python的list.index()方法,先正序找到起始位置,再逆序找到结束位置,并给出了两种方法的Python实现代码。
72 0
|
5月前
|
Python
【Leetcode刷题Python】203.移除链表元素
文章提供了三种删除链表中特定值节点的方法:迭代法、虚拟节点迭代删除法和递归法,并给出了相应的Python实现代码。
29 0