C ++のSTL優先キュー
最大および最小ヒープを構築する方法
priority_queue<int> big_heap; // 默认构造最大堆
priority_queue<int, vector<int>, greater<int>> small_heap; // 构造最小堆
priority_queue<int, vector<int>, less<int>> big_heap2; // 构造最大堆
優先キューとその機能例
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
// 以下为测试
int main() {
priority_queue<int> big_heap; // 默认构造最大堆
priority_queue<int, vector<int>, greater<int>> small_heap; // 构造最小堆
priority_queue<int, vector<int>, less<int>> big_heap2; // 构造最大堆
if (big_heap.empty()) {
cout << "最大堆为空!" << endl;
}
int test[] = {
6,10,1,7,99,4,33 };
for (int i = 0; i < 7; i++) {
big_heap.push(test[i]);
}
cout << "最大堆堆顶,即最大值为 " << big_heap.top() << endl;
big_heap.push(1000);
cout << "最大堆堆顶,即最大值为 " << big_heap.top() << endl;
for (int i = 0; i < 3; i++)
{
big_heap.pop();
}
cout << "最大堆堆顶,即最大值为 " << big_heap.top() << endl;
cout << "最大堆的元素个数为:" << big_heap.size() << endl;
return 0;
}
結果:
最大堆为空!
最大堆堆顶,即最大值为 99
最大堆堆顶,即最大值为 1000
最大堆堆顶,即最大值为 10
最大堆的元素个数为:5
配列内でK番目に大きい要素を見つけます
- 問題:ソートされていない配列でk番目に大きい要素を見つけます。見つける必要があるのは、配列をソートした後のk番目に大きい要素であり、k番目に異なる要素ではないことに注意してください。
- 解決策:サイズがKの最小チームを維持します。ヒープ内の要素の数がK未満の場合、新しい要素は直接ヒープに入ります。そうでない場合、ヒープの一番上の要素が新しい要素よりも小さい場合、ヒープの一番上がポップされ、新しい要素がヒープに追加されます。
- 例:[3,2,1,5,6,4]およびk = 2、k = 2であるため、最初の3および2は最小のヒープに直接入力され、ヒープの最上部は2であり、1より大きいため、操作は不要であり、2は5より大きい。 5がヒープに入ったが、2がポップアウトされた場合など、2つの要素の最小のヒープが形成されます。ヒープの上部は5で、これは必要なK番目の最大数です。その理由は、2つの(k)番号のうち最小のものが、6つの番号の中で2番目に大きいためです。味わい、上品な味わい!
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int>> Q;
for (int i = 0; i < nums.size(); i++)
{
if (Q.size() < k)
Q.push(nums[i]);
else if (Q.top() < nums[i]) {
Q.pop();
Q.push(nums[i]);
}
}
return Q.top();
}
};
データセットの中央値を見つける
問題
データセットの中央値を見つけます。中央値は、順序付きリストの中央にある数値です。リストの長さが偶数の場合、中央値は中央の2つの数値の平均です。
たとえば
、[2,3,4]の中央値は3です。
[2,3]の中央値は(2 + 3)/ 2 = 2.5です。
次の2つの操作をサポートするデータ構造を設計します。
- void addNum(int num)-データストリームからデータ構造に整数を追加します。
- double findMedian()-現在のすべての要素の中央値を返します。
解決する
-
アイデア:最大ヒープと最小ヒープを動的に維持します。それぞれがデータの半分を格納します。ただし、最大のヒープの上部が最小のヒープの上部よりも小さい(または等しい、つまりデータがサイズに応じて2つに分割される)場合に限ります。半分。データセット全体の要素数が奇数の場合、一方のヒープにはもう一方の要素よりも1つ多い要素があります。つまり、複数要素のヒープの最上部が中央値です。要素の数が偶数の場合、次に、2つの山の上部要素の平均を中央値とします。
-
アルゴリズムは主に、新しいデータを追加するときに最大ヒープと最小ヒープを維持します。次の3つの状況があります。
- ケース1、現在の最大ヒープ要素と最小ヒープ要素が同じである場合は、次のことを確認します。新しい要素が最大ヒープの上限よりも小さい場合は、最大ヒープに追加します。新しい要素が最小ヒープの上限よりも大きい場合は、最小ヒープに追加します。
- ケース2:最大のヒープが最小のヒープより1要素多い場合は、次のことを確認します。新しい要素が最大のヒープ要素よりも大きい場合は、最小のヒープに追加します。そうでない場合は、新しい要素が最大のヒープ要素以下である場合は注意してください。現時点では、最大のヒープに直接追加することはできません(最大のヒープ操作は、最小のヒープより2つ多い要素で完了します)。正しくは、バランスを維持するために、最大のヒープの一番上の要素を最小のヒープに追加してポップしてから、新しい要素を最大のヒープに追加する必要があります。若い女の子。
- ケース3:最小ヒープには、最大ヒープよりも1つ多い要素があります。これは、上記の考え方と一致しています。
完全なコード:
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
class MedianFinder {
public:
/** initialize your data structure here. */
MedianFinder() {
}
// 数据加入及最大堆和最小堆的维护
void addNum(int num) {
if (big_heap.empty()) {
big_heap.push(num);
return;
}
// 情况1
if (big_heap.size() == small_heap.size()) {
if (num < big_heap.top()) {
big_heap.push(num);
}
else {
small_heap.push(num);
}
}
// 情况2
else if (big_heap.size() > small_heap.size()) {
if (num > big_heap.top())
small_heap.push(num);
else {
small_heap.push(big_heap.top());
big_heap.pop();
big_heap.push(num);
}
}
// 情况3
else if (big_heap.size() < small_heap.size()) {
if (num < small_heap.top())
big_heap.push(num);
else {
big_heap.push(small_heap.top());
small_heap.pop();
small_heap.push(num);
}
}
}
// 求中位数
double findMedian() {
if (big_heap.size() == small_heap.size()) {
return (double(big_heap.top()) + small_heap.top()) / 2.0;
}
else if (big_heap.size() > small_heap.size())
return big_heap.top();
return small_heap.top();
}
private:
priority_queue<int, vector<int>, less<int>> big_heap; // 构造最大堆
priority_queue<int, vector<int>, greater<int>> small_heap; // 构造最小堆
};
// 以下为测试
int main() {
MedianFinder m;
m.addNum(1);
m.addNum(2);
cout << m.findMedian() << endl;
m.addNum(3);
cout << m.findMedian() << endl;
return 0;
}
結果:
1.5
2
ps:この記事はリトルエレファントアカデミーチュートリアルのメモです:https
://www.bilibili.com/video/BV1GW411Q77S ?t = 7029&p = 2 LeetCodeタイトル番号:215,295