算法知识-堆相关知识

一.对顶堆

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;
}
相关推荐
李伟_Li慢慢1 小时前
从惯性和矩详解惯性矩
人工智能·算法·机器人
黎阳之光1 小时前
实景三维重构赋能智慧仓储,黎阳之光打造仓库全域透明管控新生态
大数据·人工智能·算法·安全·数字孪生
vigor5121 小时前
异步服务的调用处理
算法
wuweijianlove1 小时前
算法的渐进复杂度与现实执行性能差异研究的技术6
算法
黎阳之光1 小时前
黎阳之光:以原创硬核通信,定义无人系统与应急指挥新边界|7030‑46无线图数自组网电台技术解析
大数据·人工智能·物联网·算法·数字孪生
小许同学记录成长1 小时前
gr-filter 滤波与多速率模块完整源码分析
算法·信号处理
Dxy12393102161 小时前
js中Math.min.apply()详解
开发语言·javascript
摇滚侠1 小时前
Java 零基础全套教程,File 类与 IO 流,笔记 175-176
java·开发语言·笔记
不知名的老吴2 小时前
经典算法实战:重新排列日志文件(二)
数据结构·算法