算法知识-堆相关知识

一.对顶堆

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;
}
相关推荐
逃逸线LOF33 分钟前
服务网关Gateway
java·运维·gateway
Funlang1 小时前
给机器写的 JavaScript 造个笼子
开发语言·javascript·ecmascript
普通人61 小时前
PHP文件读写完全指南
开发语言·php·1024程序员节
灿飞屋1 小时前
Kotlin与Java虚拟机四:函数
java·python·kotlin·安卓·android jetpack
武子康1 小时前
Qwen-Drive 到底是什么:4B 级 VLM 如何成为驾驶策略底座
人工智能·算法·机器学习
坤坤子吖2 小时前
Linux网络编程:TCP服务器的多进程与多线程实现
linux·服务器·开发语言·网络·c++·笔记·学习
阡陌数智2 小时前
Claude API新版本重大变更与安全升级指南
java·linux·安全
一晌小贪欢2 小时前
Python基础:第 09 篇 · while 循环:重复直到不满足
开发语言·c++·python·数据可视化·面向对象·python办公
zh_xuan2 小时前
LeeCode 496. 下一个更大元素I
数据结构·算法·栈·单调栈
机 _ 长3 小时前
05 智算运维|8 张卡怎么才算「捆成一张」:NCCL 实测与拓扑
运维·人工智能·算法·智算运维