算法知识-堆相关知识

一.对顶堆

1.作用

可以动态维护一个序列上第 k 大的数,k 值会发生变化。比写 线段树 或 BST 简单。

2.算法思想

对顶堆由一个大根堆与一个小根堆组成,小根堆维护前 k 大的数(包含第 k 个,小根堆装大的数),大根堆维护比第 k 大数小的数(大根堆装小的数)

  1. 插入:若插入的元素 ≥ 小根堆堆顶元素,则将其插入小根堆,否则将其插入大根堆。
  2. 维护:当小根堆的大小 > k 时,不断将小根堆堆顶元素取出并插入大根堆,直到小根堆的大小等于 k;
    当小根堆的大小 < k 时,不断将大根堆堆顶元素取出并插入小根堆,直到小根堆的大小等于 k。
  3. 查询第 k 大元素:小根堆堆顶元素。
  4. 删除第 k 大元素:删除小根堆堆顶元素。

D - Chalkboard Median

题意:给你一个数x,之后每次固定向里面加入两个数字,之后每次求这个序列的中位数

解题思路:

这是动态求第k大的问题,我们使用对顶堆

cpp 复制代码
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
class DuiDing {
private:
    // 大根堆:存较小的那一半数
    priority_queue<int> big;
    // 小根堆:存较大的那一半数(前 k 大)
    priority_queue<int, vector<int>, greater<int>> small;

public:
    // 插入单个元素
    void insert(int x, int k) {
        // 1. 决定放入哪个堆
        // 注意:如果 small 为空,或者 x 比 small 的堆顶大(或相等),放入 small
        if (small.empty() || x >= small.top()) {
            small.push(x);
        }
        else {
            big.push(x);
        }

        // 2. 平衡两个堆的大小
        // 情况 A: small 里的数太多了(超过了 k 个),把最小的移给 big
        while (small.size() > k) {
            big.push(small.top());
            small.pop();
        }

        // 情况 B: small 里的数太少了(不足 k 个),且 big 里有货,把最大的移给 small
        //  判断,防止空指针异常
        while (small.size() < k && !big.empty()) {
            small.push(big.top());
            big.pop();
        }
    }

    // 获取第 k 大
    // 增加了一个安全检查,防止在元素不足 k 个时访问空堆
    int get_k() {
        if (small.empty()) return -1; // 或者抛出异常
        return small.top();
    }
};

int main() {
	int x; cin >> x;
	int q; cin >> q;
	DuiDing d;
	
	int cnt = 1;
    d.insert(x, 1);
    while (q--) {
		vector<int>num(2);
        int a, b; cin >> a >> b;
		d.insert(a, ++cnt);
        d.insert(b, cnt);
		cout << d.get_k()<<'\n';
	}

	return 0;
}
相关推荐
Jerry6 小时前
LeetCode 160. 相交链表
算法
认真的酒窝6 小时前
自己动手开发编译器(十一)语义分析
java·开发语言
Jerry6 小时前
LeetCode 19. 删除链表的倒数第 N 个结点
算法
金銀銅鐵6 小时前
费马小定理
python·数学·算法
wbs_scy7 小时前
Linux C++ 高并发编程:线程池全链路深度解析,从原理到手撕实现
java·开发语言
JAVA面经实录9177 小时前
Linux 常用命令完整知识体系
java·linux·开发语言·汇编
技术不好的崎鸣同学8 小时前
[ACTF2020 新生赛]Exec 思路及解法
算法·安全·web安全
贪玩的蛋挞8 小时前
C#与闭包
开发语言·c#
端庄的战斗机8 小时前
javascript 设计模式(文章很长,请自备瓜子,水果和眼药水)
开发语言·javascript·设计模式
Full Stack Developme9 小时前
Java LRU 与 LFU 算法及应用
java·开发语言·算法