【数据结构】 最大最小堆实现优先队列 python

堆的定义


堆(Heap)是一种特殊的完全二叉树结构,通常分为最大堆和最小堆两种类型。

在最大堆中,父节点的值总是大于或等于其子节点的值;

而在最小堆中,父节点的值总是小于或等于其子节点的值。

堆常用于实现优先队列,在许多算法中也有重要应用,比如堆排序、Dijkstra算法等。

堆的基本操作

  • 插入:向堆中添加一个新元素,并调整堆以保持其性质。

  • 删除:移除堆顶元素(最大或最小元素),并重新调整堆。

  • 获取最大/最小元素:直接访问堆顶元素即可获得。

堆的实现

Python 的 heapq 模块提供了对堆的支持,它实现了最小堆。以下是一个简单的例子:

import heapq# 创建一个空堆
heap = []# 向堆中插入元素
heapq.heappush(heap, 10)
heapq.heappush(heap, 20)
heapq.heappush(heap, 5)
print(heap)# 获取堆顶元素(最小元素)
min_element = heap[0]
print("堆顶元素:", min_element)# 移除堆顶元素
heapq.heappop(heap)
print("移除堆顶元素后的堆:", heap)# 如果需要使用最大堆,可以通过插入负值来模拟
max_heap = []
heapq.heappush(max_heap, -10)
heapq.heappush(max_heap, -20)
heapq.heappush(max_heap, -5)
print(heap)max_element = -max_heap[0]  # 记得取负数得到原始的最大值
print("最大堆顶元素:", max_element)

注意:为了实现最大堆,我们需要存储元素的负值

因为 Python 标准库中的heapq 模块只提供最小堆的功能。



【模板】堆

题目描述

给定一个数列,初始为空,请支持下面三种操作:

  1. 给定一个整数 x x x,请将 x x x 加入到数列中。
  2. 输出数列中最小的数。
  3. 删除数列中最小的数(如果有多个数最小,只删除 1 1 1 个)。

输入格式

第一行是一个整数,表示操作的次数 n n n
接下来 n n n 行,每行表示一次操作。每行首先有一个整数 o p op op 表示操作类型。

  • o p = 1 op = 1 op=1,则后面有一个整数 x x x,表示要将 x x x 加入数列。
  • o p = 2 op = 2 op=2,则表示要求输出数列中的最小数。
  • o p = 3 op = 3 op=3,则表示删除数列中的最小数。如果有多个数最小,只删除 1 1 1 个。

输出格式

对于每个操作 2 2 2,输出一行一个整数表示答案。

输入输出样例 #1

输入 #1

5
1 2
1 5
2
3
2

输出 #1

2
5

说明/提示

【数据规模与约定】

  • 对于 30 % 30\% 30% 的数据,保证 n ≤ 15 n \leq 15 n15
  • 对于 70 % 70\% 70% 的数据,保证 n ≤ 1 0 4 n \leq 10^4 n104
  • 对于 100 % 100\% 100% 的数据,保证 1 ≤ n ≤ 1 0 6 1 \leq n \leq 10^6 1n106 1 ≤ x < 2 31 1 \leq x \lt 2^{31} 1x<231 o p ∈ { 1 , 2 , 3 } op \in \{1, 2, 3\} op{1,2,3}

AC_code:

import heapq
hp = []
n = int(input())
for _ in range(n):a = list(map(int, input().split()))op = a[0]if op == 1:heapq.heappush(hp, a[1])elif op == 2:print(hp[0])else:heapq.heappop(hp)


实战演练


牛客周赛 Round 82 E题 和+和

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


方法思路


我们需要从两个数组中选择2m个下标,使得前m个下标对应的a数组元素之和加上后m个下标对应的b数组元素之和最小。关键在于高效地找到这些下标的最优组合。
  1. 预处理前缀和后缀数组

    • pre_a[k]:表示在前k个元素中选择m个最小的a数组元素之和。
    • suf_b[k]:表示从第k个元素到末尾中选择m个最小的b数组元素之和。
  2. 使用大根堆维护最小元素

    • 遍历数组时维护一个大根堆,确保堆中始终保存当前最小的m个元素。当堆的大小超过m时,弹出最大的元素,保持堆的大小为m。
  3. 遍历所有可能的分割点

    • 对于每个可能的分割点k,计算前k个元素的最小m个a之和,加上从k+1到末尾的最小m个b之和,取最小值。

AC_code:

import heapqn, m = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))pre_a = [float('inf')] * (n + 1)
heap = []  # 最大堆(通过存储负数模拟)
sum_a = 0  for i in range(1, n + 1):heapq.heappush(heap, -a[i - 1])  # 将当前元素加入堆中(存入负数表示最大堆)sum_a += a[i - 1]  # 如果堆的大小超过 m,则移除堆顶元素(即最大的那个)if len(heap) > m:removed = -heapq.heappop(heap)sum_a -= removed# 如果堆中有正好 m 个元素,则记录当前的前缀和if len(heap) == m:pre_a[i] = sum_a# 初始化后缀和数组 suf_b
suf_b = [float('inf')] * (n + 2)
heap = []  # 清空堆
sum_b = 0 # 计算后缀和
for i in range(n, 0, -1):heapq.heappush(heap, -b[i - 1])  # 将当前元素加入堆中(存入负数表示最大堆)sum_b += b[i - 1]  # 如果堆的大小超过 m,则移除堆顶元素(即最大的那个)if len(heap) > m:removed = -heapq.heappop(heap)sum_b -= removed# 如果堆中有正好 m 个元素,则记录当前的后缀和if len(heap) == m:suf_b[i] = sum_bans = float('inf')
for k in range(m, n-m + 1):ans = min(ans, pre_a[k] + suf_b[k+1])print(ans)

代码解释

  1. 预处理前缀数组pre_a

    • 使用大根堆维护前k个元素中最小的m个元素之和。每次添加元素后,若堆的大小超过m,则弹出最大元素,保持堆的大小为m,确保sum_a始终是前k个元素中最小的m个之和。
  2. 预处理后缀数组suf_b

    • 从后往前遍历b数组,同样使用大根堆维护从当前元素到末尾的最小的m个元素之和。处理方式与pre_a类似,确保sum_b是当前处理段的最小m个元素之和。
  3. 遍历分割点k

    • 遍历所有可能的k值,计算pre_a[k](前k个元素的最小m个a之和)和suf_b[k+1](从k+1到末尾的最小m个b之和)的总和,取最小值作为结果。

这种方法利用堆高效地维护了最小的m个元素之和,预处理时间复杂度为O(n log m),遍历分割点的复杂度为O(n),整体复杂度为O(n log m),适用于大规模数据。


END
如果有更多问题或需要进一步的帮助,可以在评论区留言讨论哦!
如果喜欢的话,请给博主点个关注 谢谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/25529.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重新审视 ChatGPT 和 Elasticsearch:第 2 部分 - UI 保持不变

作者&#xff1a;来自 Elastic Jeff Vestal 本博客在第 1 部分的基础上进行了扩展&#xff0c;介绍了基于 RAG 的搜索系统的功能齐全的 Web UI。最后&#xff0c;你将拥有一个将检索、搜索和生成过程结合在一起的工作界面&#xff0c;同时使事情易于调整和探索。 不想读完整个内…

【开源】低代码 C++程序框架,Linux多线程程序

大家好&#xff0c;欢迎来到停止重构的频道。 本期介绍我们新的C低代码框架&#xff1a;Bees&#xff0c;用于编写Linux/Unix的多线程程序。 低代码框架一般是不会对C程序下手的&#xff0c;因为C程序一般是比较复杂的程序&#xff0c;光是多线程同步就够头疼的了。 但是我们…

数据库的sql语句

本篇文章主要用来收集项目开发中&#xff0c;遇到的各种sql语句的编写。 1、根据user表的role_id字段&#xff0c;查询role表。 sql语句&#xff1a;使用JOIN连接两个表 SELECT u.*,r.rolename FROM user u JOIN role r ON u.role_id r.id WHERE u.id 1; 查询结果&#xff1a…

从零开始用react + tailwindcs + express + mongodb实现一个聊天程序(二)

1.安装mogondb数据库 参考MongoDB安装配置教程&#xff08;详细版&#xff09;_mongodb安装详细步骤-CSDN博客 安装mondbcompass数据库连接工具 参考https://www.mongodb.com/zh-cn/docs/compass/current/connect/ 2.后端服务 1.创建src文件夹 并在src文件夹下创建 index…

opencv:距离变换 cv2.distanceTransform

函数 cv2.distanceTransform() 用于计算图像中每一个非零点像素与其最近的零点像素之间的距离&#xff08;Distance Transform&#xff0c; DT算法&#xff09;,输出的是保存每一个非零点与最近零点的距离信息&#xff1b;图像上越亮的点&#xff0c;代表了离零点的距离越远。 …

单目摄像头物体深度计算基础原理

三维空间物体表面点位与其在图像中对应点之间的相互关系&#xff0c;必须建立相机成像的几何模型&#xff0c;这些几何模型参数就是相机参数&#xff0c;而相机参数的求解就是相机标定。 相机的参数矩阵包括内参和外参&#xff1a; 外参&#xff1a;决定现实坐标到摄像机坐标。…

RabbitMQ系列(一)架构解析

RabbitMQ 架构解析 RabbitMQ 是一个基于 AMQP 协议的开源消息中间件&#xff0c;其核心架构通过多组件协作实现高效、可靠的消息传递。以下是其核心组件与协作流程的详细说明&#xff1a; 一、核心组件与功能 Broker&#xff08;消息代理服务器&#xff09; RabbitMQ 服务端核…

Spring Cloud Alibaba与Spring Boot、Spring Cloud版本对应关系

一、前言 在搭建SpringCloud项目环境架构的时候&#xff0c;需要选择SpringBoot和SpringCloud进行兼容的版本号&#xff0c;因此对于选择SpringBoot版本与SpringCloud版本的对应关系很重要&#xff0c;如果版本关系不对应&#xff0c;常见的会遇见项目启动不起来&#xff0c;怪…

[Web 信息收集] Web 信息收集 — 手动收集域名信息

关注这个专栏的其他相关笔记&#xff1a;[Web 安全] Web 安全攻防 - 学习手册-CSDN博客 0x01&#xff1a;信息收集 —— 域名联系人信息 当我们知道目标的域名之后&#xff0c;我们要做的第一件事就是获取域名的注册信息&#xff0c;包括该域名的 DNS 服务器信息和注册人的联系…

基于Rook的Ceph云原生存储部署与实践指南(上)

#作者&#xff1a;任少近 文章目录 1 Ceph环境准备2 rook部署ceph群集2.1 Rook 帮助地址2.2 安装ceph2.3 获取csi镜像2.4 Master参加到osd2.5 设置默认存储 3 Rook部署云原生RBD块存储3.1 部署storageclass资源3.2 部署WordPress使用RBD3.3 WordPress访问 4 Rook部署云原生RGW…

使用Crawlee可破题js渲染采集数据

使用 Crawlee 实现自动化爬虫流程 1. Crawlee 简介 Crawlee 是一个强大的爬虫框架&#xff0c;用于快速构建和维护可靠的爬虫。它支持多种爬虫类型&#xff0c;包括基于 Cheerio 和 Playwright 的爬虫&#xff0c;能够高效处理静态和动态网页。 2. 项目目标 通过自动化脚本实…

二、IDE集成DeepSeek保姆级教学(使用篇)

各位看官老爷好&#xff0c;如果还没有安装DeepSeek请查阅前一篇 一、IDE集成DeepSeek保姆级教学(安装篇) 一、DeepSeek在CodeGPT中使用教学 1.1、Edit Code 编辑代码 选中代码片段 —> 右键 —> CodeGPT —> Edit Code, 输入自然语言可编辑代码&#xff0c;点击S…

threejs 安装教程

嗨&#xff0c;我是小路。今天主要和大家分享的主题是“threejs 安装教程”。 在当今的数字化时代&#xff0c;用户对视觉体验的要求越来越高。传统的2D网页已经无法满足所有需求&#xff0c;而三维&#xff08;3D&#xff09;图形技术则为前端开发者提供了新的方向。…

2025 软件供应链安全情报预警平台建设与实践

何为数字安全供应链情报&#xff1f; 所谓的数字供应链开源安全情报主要针对目标是开源数字应用资产。包括开源组件&#xff0c;中间件和操作系统。开源安全情报类型可以分为三大类&#xff1a; 1 第一类是传统的安全漏洞风险情报&#xff0c;开源漏洞情报数据获取主要有2种渠…

Linux:ELF文件-静动态库原理

✨✨所属专栏&#xff1a;Linux✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ ELF文件 什么是编译&#xff1f;编译就是将程序源代码编译成能让CPU直接执行的机器代码 如果我们要编译一个 .c文件&#xff0c;使用gcc -c将.c文件编译为二进制文件.o &#xff0c;如果一个项目有多个.…

批量给 Word 添加或设置页眉页脚/页码

在 Word 文档中我们可以设置各种各样的页眉页脚信息&#xff0c;比如设置页码信息、在页眉页脚中插入公司的 logo 信息、联系方式信息等等。当我们有大量的文档需要设置或者修改页眉页脚的时候&#xff0c;今天介绍的方法就可以帮我们快速的完成。 使用场景 批量给 Word 文档设…

GIST框架:深度学习助力组织病理学与转录组学的空间整合分析|顶刊精析·25-02-24

小罗碎碎念 随着空间分子成像技术发展&#xff0c;单细胞空间转录组&#xff08;SCST&#xff09;数据为研究组织微环境提供了丰富信息&#xff0c;但数据质量问题和现有分析方法的局限性阻碍了深入研究。GIST框架借助预训练的组织学图像基础模型提取详细形态特征&#xff0c;…

DeepSeek入门学习

参考文档&#xff1a;DeepSeek&#xff08;人工智能企业&#xff09;_百度百科 DeepSeek-R1 凭借创新的强化学习技术实现重大突破。在极少量标注数据的基础上&#xff0c;通过深度优化的后训练阶段&#xff0c;显著提升了模型的推理能力。在数学运算、代码生成、自然语言推理等…

RTSP/Onvif安防平台EasyNVR接入EasyNVS显示服务缺失的原因与解决方案

EasyNVS云管理平台具备强大的汇聚与管理功能&#xff0c;支持EasyGBS、EasyNVR等平台的接入&#xff0c;能够将接入的视频资源进行统一输出&#xff0c;提供远程可视化运维等管理功能&#xff0c;特别适合解决设备现场没有固定公网IP但仍需在公网直播的需求。 在某次用户现场部…

【计算机网络协议02】详解传输层协议TCP/UDP

传输层 传输层是OSI模型的第四层&#xff0c;主要负责端到端的数据传输&#xff0c;确保数据可靠、有> 序地从源设备传送到目标设备。其主要功能包括&#xff1a; 端到端通信&#xff1a;在源和目标设备之间建立连接&#xff0c;确保数据准确传输。数据分段与重组&#xff1…