Leetcode刷题 - Top K 系列

347. Top K Frequent Elements

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        // hash map 储存frequency
        unordered_map<int, int> map;
        for (int num : nums)
            map[num]++;
         
        vector<int> ans;
        // use priority queue to build max heap
        priority_queue<pair<int,int>> pq;
        // 迭代map加入堆中,寻找最大频率对应的数
        for(auto iter = map.begin(); iter != map.end(); iter ++){
            pq.push(make_pair(iter->second, iter->first));
            if (pq.size() > map.size() - k){
                ans.push_back(pq.top().second);
                // 加入ans中,弹出堆顶元素
                pq.pop();
            }
        }
        return ans;
    }
};

 

692. Top K Frequent Words 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
public:
    vector<string> topKFrequent(vector<string>& words, int k) {
        //初始化hashmap
        unordered_map<string, int> map;
        for (string s : words)
            map[s]++;
         
        vector<string> ans;
        //初始化最小堆
        //自定义 compare
        // 若次数相同,则按字母来排序
        // return true if a is considered to go before b
        auto comp = [](pair<int, string>& a, pair<int, string>& b){ return a.first == b.first ? a.second < b.second : a.first > b.first; };
        priority_queue<pair<int, string>, vector<pair<int, string> >, decltype(comp)>pq(comp);
        // 调整最小堆
        for (auto iter = map.begin(); iter != map.end(); iter++){
            pq.push(make_pair(iter->second, iter->first));
            if (pq.size () > k) pq.pop();
        }
        // 加入结果
        while(!pq.empty()) {
            ans.push_back(pq.top().second);
            pq.pop();
        }
        //翻转结果
        reverse(ans.begin(), ans.end());
        return ans;
    }
};

  

215. Kth Largest Element in an Array

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        // 建一个大小为2的最小堆
        priority_queue<int, vector<int>, greater<int>> pq;
        for (int n : nums){
            pq.push(n);
            if (pq.size() > k) pq.pop();
        }
         
        return pq.top();
    }
};

 

973. K Closest Points to Origin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public:
    vector<vector<int>> kClosest(vector<vector<int>>& points, int K) {
        //建立一个长度为k的最小堆
        auto comp = [](vector<int>& a, vector<int>&b){return a[0]*a[0] + a[1]*a[1] < b[0]*b[0] + b[1]*b[1];};
        priority_queue<vector<int>, vector<vector<int>>, decltype(comp)> pq (comp);
        //添加元素,调整堆
        for(vector<int> temp : points){
            pq.push(temp);
            if(pq.size() > K){
                pq.pop();
            }
        }
        //输出结果
        vector<vector<int>> ans;
        while(!pq.empty()){
            ans.push_back(pq.top());
            pq.pop();
        }
        return ans;
    }
};

  

451. Sort Characters By Frequency

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public:
    string frequencySort(string s) {
        // hashmap to store the frequency
        unordered_map<char, int> map;
        for (char ch:s)
            map[ch]++;
         
        //建立一个最大堆
        priority_queue<pair<int, char>> pq;
        for (auto m : map)
            pq.push({m.second, m.first});
         
        // 输出结果
        string result = "";
        while(!pq.empty()){
            /********************************************
            * string (size_t n, char c) :frequency times the character
            **********************************************/
            result += string(pq.top().first, pq.top().second);
            // result.push_back(pq.top().first);
            pq.pop();
        }
        return result;
    }
};

  

总结

1. 识别最大K个元素模式:

  • 如果你需要求最大/最小/最频繁的前K个元素
  • 如果你需要通过排序去找一个特定的数

2. 步骤

  • 初始化堆:priority_queue
  • 确定堆的属性:STL默认为最大堆, 并根据int type进行排序。也可以用compare自行写判断条件
1
2
auto comp = [](pair<int, string>& a, pair<int, string>& b){ return a.first == b.first ? a.second < b.second : a.first > b.first; };
priority_queue<pair<int, string>, vector<pair<int, string> >, decltype(comp)>pq(comp); 
  • 将数据插入堆中,调整堆

 

参考资料

  1. https://leetcode.com/problems/top-k-frequent-elements/
  2. https://leetcode.com/problems/top-k-frequent-words/
  3. https://leetcode.com/problems/kth-largest-element-in-an-array/
  4. https://leetcode.com/problems/k-closest-points-to-origin/
  5. https://leetcode.com/problems/sort-characters-by-frequency/

__EOF__

本文作者cancantrbl
本文链接https://www.cnblogs.com/cancantrbl/p/13658891.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   cancantrbl  阅读(1110)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示