ご存知のように、map 構造はデフォルトでキー値に基づいて小さいものから大きいものへと並べ替えることができますが、unordered_map は map よりも高速かつ便利にデータを処理します。
質問をするとき、 unordered_map をキーに基づくマップに置き換えることができますが、値をソートする必要がある場合もあります
たとえば、次のトピック:
まず第一に、ハッシュテーブルを使用して各要素の出現回数を格納する必要があります.最初のk個の優先度の要素を取得するために、ソートが大きな問題になりました.
ピット回避経験:
Unordered_map は、公式ドキュメントで説明されているカスタム ソートに sort を使用できません。
したがって、優先キューであるヒープを使用します
ヒープは、大きなトップ ヒープと小さなトップ ヒープに分けられ、大きなトップ ヒープはキューの先頭に最大の要素を配置し、小さなトップ ヒープは最小の要素をキューの先頭に配置します。キューの先頭。ヒープ宣言はデフォルトで大きなトップ ヒープに設定されており、キューを最大の要素として簡単に取得できます。
キューの順序に関しては、ヒープは最大の値をキューの先頭に置くだけであり、キューを厳密に並べ替えるわけではありません。
大きなトップ ヒープを宣言します。ヘッダー ファイルを参照する必要があります: #include<queue>
priority_queue<int> p;
基本的なデータ型 (int、char など) の場合、小さなトップ ヒープに独自の比較関数があることを宣言します。
priority_queue<int, vector<int>, greater<int> > q;
priority_queue のパラメーター リストの場合: 1 番目はデータ型、2 番目はストレージ タイプのコンテナー コンテナー (通常は vector<typename>)、3 番目は比較関数です。後の 2 つのパラメーターは、大きなトップ ヒープの場合は省略できます。 .
greater<int> は、小さなトップ ヒープの組み込み比較関数です。
しかし、pair<int,int> (チーム グループ) のようなデータ型の場合、priority_queue には独自の比較関数がありません. 独自の比較関数を記述する必要があるだけでなく、宣言も少し異なります:
// 比較関数
static bool cmp(pair<int,int>& a, pair<int,int>b){
a.second > b.second を返します。
}
//声明
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> q(cmp);
decltype 関数は自動型推論で、pair<int, int> などのより複雑なデータ型を識別できますが、比較関数のアドレスを渡す必要があります
小さなトップ ヒープを使用して、unordered_map 内の小さな要素を連続的に取り出しますが、これはスクリーニングのレイヤーと見なすことができます。
次に、この質問のコードを見てください。
class Solution {
public:
static bool cmp(pair<int,int>& a, pair<int,int>b){
return a.second > b.second;
}
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int>ump;
int n = nums.size();
vector<int>ans;
for(int i = 0; i < nums.size(); i++){
ump[nums[i]]++;
}
//创建一个pair类型的小顶堆
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> q(cmp);
//decltype用于自动类型推断、将pair依照value值把最小的放在前面
// a是nums[i]数值,b是此数值出现的次数
for(auto& [a,b] : ump){
if(q.size() == k){
if(q.top().second < b){
q.pop();
q.emplace(a,b);
}
}
else q.emplace(a,b);
}
while(q.size() != 0){
ans.push_back(q.top().first);
q.pop();
}
return ans;
}
};
あなたと共有したい!