首页 > 其他分享 >【笔记】可删除堆

【笔记】可删除堆

时间:2023-11-14 20:12:28浏览次数:31  
标签:q1 删除 堆顶 元素 笔记 取出 我们

可删除堆

考虑到没什么人会选择手写普通的堆,所以用优先队列实现就好。

问题:

我们知道,在使用堆或优先队列的时候,我们只能取出堆顶,也就是所维护的最大或最小值。

那么如果我们要从所维护的一个元素里删除一个非最大或最小值呢?

最暴力的做法是将元素一个一个从堆顶弹出,直到弹出我们要删的元素,再将之前所弹出的不需要删的元素放回堆里。

这样做显然是不能接受的。

思考:

我们现在考虑,如果我们选择摆烂无视掉删除操作,继续往后执行任务,似乎也不一定会出错。

如果我们需要删的数是当时堆里第 \(k\) 大的数,现在我们需要取出堆里前 \(k-1\) 大的数。那么我们的操作将不会取出这个要删的数,所取出的这些数也是正确的结果。换而言之,只要我们查询时不需要取出这个要删的数,那么这个要删的数就不会对我们的答案产生影响。

只有当我们取出一个本应删除的数时,答案才会出错。

原理:

对于一个堆,我们真正需要的是它的对顶,只要对顶始终保持正确,对顶底下的数是什么对我们所以到的堆是没有影响的,堆里的数唯一的用处就是选出堆顶和成为堆顶。

那么我们只需要保证一个堆的堆顶的数正确就好了。

实现:

思路类似对顶堆。

我们再准备一个删除堆,删除堆和我们要用的堆一样,我们要用的堆是大根堆或小根堆,这个删除堆就也是大根堆或小根堆。

当我们要从堆里删一个数 \(k\) 时,我们将 \(k\) 放入删除堆的对顶,要用的堆则不需要操作。

当我们查询时,我们在将对顶从要用的堆中取出时,如果发现这个堆顶和删除堆的堆顶一致,那么两个堆就都弹出这个元素,并将这个元素扔掉(不使用这个元素)。重复上述操作,直到我们将该取出的元素都从要用的堆里取出,或者删除堆被删空。

时间复杂度:

删除:每删一个数就相当于向堆里放一个数的复杂度。

询问:询问时的复杂度取决于我们取出堆顶元素是不是要删的数。

都不会太大,基本可以看做是一个常数大点的堆。

代码:

点击查看代码
namespace ksd{ //封装一下。 
    priority_queue<int>q1; //用这个堆存放需要维护的数。
	priority_queue<int>q2; // 用这个堆存放需要删除的数。
	//绝大多数情况没必要额外写以下几个函数 
	void Insert(int x){ //插入一个值为x的数
		q1.push(x);
	} 
	void POP(int x) { // 删除一个值为x的数。 
		q2.push(x);
	} 
	int query() { //查询堆顶元素 
		while(!q1.empty()&&!q2.empty()&&q1.top()==q2.top()) q1.pop(),q2.pop();
		return q1.top();
	}
}

补充:

如果需要删的数需要考虑这个数的键值(或者说下标),那么就将堆维护的元素改成pair,多维护一个键值(我还是更喜欢叫下标)即可。

标签:q1,删除,堆顶,元素,笔记,取出,我们
From: https://www.cnblogs.com/int-Hello-world/p/17832424.html

相关文章

  • JUC并发编程学习笔记(十九)原子引用
    原子引用带版本号的原子操作!解决ABA问题,引入原子引用(乐观锁思想)AtomicStampedReference类解决ABA问题packageorg.example.cas;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.atomic.AtomicStampedReference;//使用原子引用解决ABA问题publiccl......
  • 前端学习-JavaScript学习-JavaScript高级程序设计-第2章笔记
    在HTML中使用JavaScript元素<script>元素元素属性MDN<script>:脚本元素属性使用状态描述charset可选、少用字符集defer可选、少用表示脚本可以延迟至文档完全被解析后实行,部分浏览器不支持language废弃编写代码使用的语言src可选包含要执行代码的......
  • 【笔记】曼哈顿距离与切比雪夫距离的互化
    【笔记】曼哈顿距离与切比雪夫距离的互化图源:https://www.cnblogs.com/SGCollin/p/9636955.html曼哈顿距离:\(|x_a-x_b|+|y_a-y_b|\)切比雪夫距离:\(\max(|x_a-x_b|,|y_a-y_b|)\)在有的题目中,要求是一种距离,但使用另一种距离更加方便。比如曼哈顿距离就可以将两维拆......
  • 任何用let或const声明的属性不能够从它被声明的作用域中删除。任何使用 var 声明的属
    请问以下JS代码的输出结果是什么?leta=1;letobj={x:1}deletea;deleteobj.x;delete2;console.log(a);console.log(obj.x);console.log(2);A1、1、2B1、undefined、2C1、undefined、undefinedDundefined、undefined、undefined正确答案:B需要明确的......
  • 【笔记】二进制拆分
    二进制拆分二进制拆分是对多重背包的一种优化方式,可以极大的优化多重背包的时间。原理一个数可以被拆分为任意二进制的和。例如:$7=2^0+2^1+2^2$任意一个数都可以表示为几个\(2\)的多少次方之和的形式。我们回顾下完全背包问题。背包容积为\(C\),有\(n\)种物品......
  • 阅读笔记五
    第六章:对象和数据结构对象暴露行为,隐藏数据,便于添加新对象类型而无须修改既有行为,同时难以在既有对象中添加新行为;数据结构暴露数据。没有明显的行为,便于向既有数据结构添加新的行为,同时难以向既有函数添加新的数据结构。数据抽象:隐藏实现关乎抽象,暴露抽象接口,以便用户无须了解......
  • kafka第七天学习笔记
    在Kafka学习的第七天,你可能会进一步深入了解Kafka的特性和工作机制。以下是一些可能的学习点:Kafka的存储机制:Kafka使用一种称为“日志文件”的存储机制,将消息作为字节流存储在硬盘上。这种存储方式使得Kafka能够高效地处理大量的数据。消息的索引:Kafka为每个分区在硬盘上创建一个索......
  • k8s 删除Terminating状态的namespace
    查看ns状态root@test-10-5-2-15:~#kubectlgetnsNAMESTATUSAGEcert-managerTerminating19h查看该命名空间下的资源kubectlapi-resources-oname--verbs=list--namespaced|xargs-n1kubectlget--show-kind--ignore-not-found-n......
  • 秦疆的Java课程笔记:32 基础 JavaDoc生成文档
    javadoc命令是用来生成自己API文档的参数信息:@author作者名@version版本号@since指明需要最早使用的JDK版本@param参数名@return返回值情况@throws异常抛出情况比如这就是一个JDK21的Oracle官方API:点击跳转packageacolyte.operator;/***这是加在类......
  • 视频直播点播平台EasyDSS无法删除分组,如何解决?
    EasyDSS视频推拉流平台可支持用户自行上传视频文件,也可将上传的点播文件作为虚拟直播进行播放。平台能支持多屏播放,可兼容Windows、Android、iOS、Mac等操作系统,还能支持CDN转推,具备较强的可拓展性与灵活性。有用户反馈,在EasyDSS上可以创建分组但删除分组时会提示无权操作,求助我们......