347. Top K Frequent Elements
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
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
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
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
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自行写判断条件
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);
- 将数据插入堆中,调整堆
参考资料
- https://leetcode.com/problems/top-k-frequent-elements/
- https://leetcode.com/problems/top-k-frequent-words/
- https://leetcode.com/problems/kth-largest-element-in-an-array/
- https://leetcode.com/problems/k-closest-points-to-origin/
- https://leetcode.com/problems/sort-characters-by-frequency/