前に書く
この質問は、Tencentの質問にこれに基づいて最初のK個の低周波要素が追加されていることを除いて、Tencentの昨日の筆記テストの質問に似ています。
件名:347. Top K高周波要素
空でない整数配列を指定すると、その中の上位k個の要素を返します。
例1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
例2:
输入: nums = [1], k = 1
输出: [1]
促す:
- 与えられたkは常に妥当であり、1≤k≤配列内の異なる要素の数であると想定できます。
- アルゴリズムの時間の複雑さは、O(n log n)よりも優れている必要があります。ここで、nは配列のサイズです。
- 質問データは一意の回答を保証します。つまり、配列内の最初のk個の高周波要素のセットは一意です。
回答は任意の順序で返すことができます。
ソース:LeetCode
リンク:https ://leetcode-cn.com/problems/top-k-frequency-elements
著作権はLeetCode が所有しています。商用転載については、正式な許可書にご連絡ください。非商用転載については、出典を明記してください。
基本的な考え方:2回マッピングする
- Unordered_mapが初めて利用可能になりました:配列の要素がキーとして使用され、要素の数が値として使用されます
- 2回目のマップの使用:キーで降順で並べ替え、要素の出現回数をキーとして使用し、要素を値として使用します。出現数が同じ要素が複数存在する可能性があるため、値はベクトルとして定義されます
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> m;
for(int i = 0; i < nums.size(); ++i){
m[nums[i]]++;//值作为键
}
map<int, vector<int>, greater<int>> sm;//按照次数从大到小排
for(auto temp : m){
sm[temp.second].push_back(temp.first);//次数作为键
}
vector<int> res;
int i = 0;
while(i < k){
for(auto temp : sm){
for(int j = 0; j < temp.second.size() && i < k; ++j){
res.push_back(temp.second[j]);
++i;
}
if(i >= k){
break;
}
}
}
return res;
}
};
基本的な考え方2:マップ+優先キュー
- Unordered_mapは要素数の統計を実現します
- Priority_queueは、要素が回数順に配置されていることを認識し、カスタムタイプを必要とします
class Solution {
public:
struct Node{
//自定义类型,元素,元素出现的次数
int val, cnt;
Node(int a, int b): val(a), cnt(b){
}
bool operator<(const Node& temp)const{
//注意该函数的定义
return cnt > temp.cnt;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
//统计数组中每一个元素出现的次数
unordered_map<int, int> m;
for(int i = 0; i < nums.size(); ++i){
m[nums[i]]++;//值作为键
}
priority_queue<Node, vector<Node>> pq;
for(auto temp : m){
if(pq.size() < k){
//队列中的元素不足k个时,直接放入队列
pq.push(Node(temp.first, temp.second));
}
else{
//超过k个时,需要确定当前的和队头的大小关系
if(temp.second > pq.top().cnt){
pq.pop();
pq.push(Node(temp.first, temp.second));
}
}
}
vector<int> res;
while(!pq.empty()){
res.push_back(pq.top().val);
pq.pop();
}
return res;
}
};