堆排序 之实现最小的K个数

news2024/11/17 3:46:38

目录

1、方式一:通过自定义实现建堆和堆化操作

2、方式二:借助模块heapq实现

2.1、模块heapq的基本使用

2.2、使用heapq实现最小的k个数

3、堆在实际项目的应用

实现语言:Python 3.9

题目来源:牛客

分析:

  • 要找到最小的k个元素,只需要准备k个数字,之后每次遇到一个数字能够快速的与这k个数字中最大的值比较(大顶堆),每次将最大的值替换掉,那么最后剩余的就是k个最小的数字了。

为什么不是与k个元素中的最小值(小顶堆)进行比较呢?

  • 我们使用示例分析为什么使用小顶堆就不能实现,对于[4, 5, 1, 6, 2, 7, 3, 8] k = 4 建立小顶堆,建立的小顶堆为[1, 5, 4, 6] 堆顶元素为1,此时使用元素2和堆顶元素比较,比堆顶元素大,不加入堆顶;那么这样可见最后得到的结果一定不是最小的k个元素,所以不能使用小顶堆。

实现步骤:

  • 1:利用input数组中前k个元素,构建一个大小为k的大顶堆,堆顶为这k个元素的最大值。
  • 2:对于后续的元素,依次比较其与堆顶的大小,若是比堆顶小,则堆顶弹出,再将新数加入堆中,直至数组结束,保证堆中的k个最小。
  • 3:最后将堆顶依次弹出即是最小的k个数。

实现方式:

  • 方式一:通过自定义实现建堆和堆化操作
  • 方式二:借助Python模块heapq实现

1、方式一:通过自定义实现建堆和堆化操作

class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # write code here
        # 建堆(从最后一个非叶子节点到根节点建堆)
        def buildHeap(a, n):
            i = n//2 - 1
            while i >=0:
                heapify(a, n, i)
                i = i - 1

        # 堆化(从上到下)
        def heapify(a, n, i):
            while True:
                maxPos = i
                # 和左子节点比较
                if i*2 + 1 <= n and a[i] < a[i*2+1]:
                    maxPos = i*2 + 1
                # 和右子节点比较
                if i*2 + 2 <= n and a[maxPos] < a[i*2+2]:
                    maxPos = i*2 + 2
                if maxPos == i:
                    break
                # 交换节点
                a[i], a[maxPos] = a[maxPos], a[i]
                i = maxPos

        # 特殊情况处理
        if len(input) == 0 or len(input) <= k:
            return input

        # 先前k个数据建堆
        buildHeap(input, k)
        # 后面的节点依次和堆顶元素比较
        # 如果比堆顶元素小,将该元素加入堆顶,然后从堆顶开始堆化
        for i in range(k, len(input)):
            if input[0] > input[i]:
                # 该元素和堆顶元素交换
                input[0], input[i] = input[i], input[0]
                # 从堆顶元素开始从上往下堆化
                heapify(input, k, 0)
        return input[:k]

2、方式二:借助模块heapq实现

  • 注意:heapq模块默认建立的是小顶堆,所以需要借助这个特性自定义实现大顶堆

2.1、模块heapq的基本使用

import heapq

# 创建一个空堆
heap = []

# 往堆中添加元素
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
heapq.heappush(heap, 4)
heapq.heappush(heap, 1)
heapq.heappush(heap, 5)
# 弹出最小元素
print(heapq.heappop(heap))  # 输出 1
print(heapq.heappop(heap))  # 输出 1

# 弹出最小元素并加入新元素
print(heapq.heapreplace(heap, 2))  # 输出 2

# 将列表转化为堆
heap = [5, 8, 3, 0, 2]
heapq.heapify(heap)
print(heap)  # 输出 [0, 2, 3, 8, 5]

# 获取最大的两个元素
print(heapq.nlargest(2, heap))  # 输出 [8, 5]
# 获取最小的两个元素
print(heapq.nsmallest(2, heap)) # 输出 [0, 2]

2.2、使用heapq实现最小的k个数

import heapq
class Solution:
    def GetLeastNumbers_Solution(self , input: List[int], k: int) -> List[int]:
        # 特殊情况处理
        if len(input) == 0 or len(input) < k or k == 0:
            return []
        # 自定义实现建立大顶堆
        def my_max_heapify(iterable):
            # 原理是对输入数据取反,这样建立的小顶堆,取数的时候进行取反即是大顶堆
            max_heap = [(-x, x) for x in iterable]
            # 建堆
            heapq.heapify(max_heap)
            # 返回max_heap中元祖数据的第二个,忽略第一个数据
            return [x for (_, x) in max_heap]

        # 前k个数据建堆
        max_heap = my_max_heapify(input[:k])
        # 后面的数据依次与堆顶元素比较
        for i in range(k, len(input)):
            if max_heap[0] > input[i]:
                # 弹出堆顶元素,加入新元素
                heapq.heapreplace(max_heap, input[i])
                # 再次对数据进行堆化
                max_heap = my_max_heapify(max_heap)

        return max_heap

3、堆在实际项目的应用

  1. 优先级队列:堆常常被用来实现优先级队列。在优先级队列中,元素被赋予一个优先级,并且总是按照优先级的顺序被处理。最大堆或最小堆可以根据需要用来实现具有最高或最低优先级元素始终位于队列头部的优先级队列。这种数据结构在任务调度、网络路由和事件处理等场景中非常有用。
  2. 堆排序:堆排序是一种基于堆的高效排序算法,其时间复杂度为O(nlogn)。它通过构建最大堆或最小堆,然后不断地取出堆顶元素(最大或最小值)并将其与堆的最后一个元素交换,然后重新调整堆的结构,直到整个数组有序。堆排序在处理大数据集时非常有效。
  3. 数据流中的Top K问题:在数据流处理中,经常需要找到数据流中最大的K个元素或最小的K个元素。这可以通过使用最大堆或最小堆来实现。具体做法是将数据流中的元素逐个插入堆中,并保持堆的大小为K。如果新插入的元素比堆顶元素(最大或最小)更大(或更小),则删除堆顶元素并插入新元素。这样,堆中始终保存着数据流中最大的K个元素或最小的K个元素。
  4. 合并有序文件:当需要合并多个有序文件为一个有序文件时,可以使用堆来实现。具体做法是将每个文件的第一个元素放入一个最小堆中,然后每次从堆中取出最小的元素并写入结果文件,然后从该元素所在的文件中取出下一个元素并重新放入堆中。重复这个过程直到所有文件都被处理完毕。
  5. 高性能定时器:在高性能定时器中,可以使用最小堆来管理定时任务。具体做法是将每个定时任务按照其触发时间放入最小堆中,然后每次从堆中取出触发时间最小的任务并执行。这样可以保证定时任务按照其触发时间的顺序被依次执行。
  6. 求解中位数:利用最大堆和最小堆,可以在O(logn)的时间内查询一组数据的中位数。具体做法是将数据分为两部分,一部分放入最大堆,另一部分放入最小堆,并保持最大堆中的元素个数不大于最小堆中的元素个数加1。这样,最大堆的堆顶元素(最大值)和最小堆的堆顶元素(最小值)的平均值就是当前数据的中位数。当插入新元素时,根据新元素与当前中位数的大小关系,将其放入最大堆或最小堆中,并重新调整两个堆的大小关系以保持平衡。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Offline: Overcoming Model Bias for Robust Offline Deep Reinforcement Learning

EAAI 2023 paper Intro model-free的离线强化学习由于价值函数估计问题存在训练的稳定性以及鲁棒性较低。本文提出基于模型的方法&#xff0c;同构构建稳定的动力学模型帮助策略的稳定训练。 method 本文基于模型的方法&#xff0c;所构造的转移模型输入状态动作&#xff0…

500元以内的蓝牙耳机品牌怎么选?五大优质品牌汇总

无论是通勤途中、学习间隙还是运动时&#xff0c;一款性能出众、价格亲民的蓝牙耳机都能为我们带来极致的听觉享受&#xff0c;然而面对市场上琳琅满目的品牌和型号&#xff0c;如何选择一款500元以内的优质蓝牙耳机&#xff0c;相信大家都会有这个难题&#xff0c;今天为了帮助…

去哪里找高清视频素材?推荐几个短视频素材免费网站

在数字时代&#xff0c;视频内容的质量直接影响观众的吸引力和留存率。尤其是高清、4K视频素材和可商用素材&#xff0c;它们在提升视觉质量和叙事深度方面起到了至关重要的作用。以下是一些国内外的顶级视频素材网站&#xff0c;它们提供的资源将为您的创作提供极大的支持和灵…

Java里的String使用

1.Java WinForm项目 public static void main(String[] args) {String testString"22";String testString2"1096";String testString3"22";Student studentnew Student();student.Age"22";Test(student.Age);Test2(student.Age); }pu…

【吴恩达机器学习-week2】多个变量的特征缩放和学习率问题

特征缩放和学习率&#xff08;多变量&#xff09; 目标 利用上一个实验中开发的多变量例程在具有多个特征的数据集上运行梯度下降探索学习率对梯度下降的影响通过 Z 分数归一化进行特征缩放&#xff0c;提高梯度下降的性能 import numpy as np np.set_printoptions(precisio…

Appwrite 1.5 已在云端发布 - 四月产品更新

Hello, Appwriters&#x1f44b; 以下是四月份的产品更新和一个令人兴奋的消息&#xff1a; Appwrite 1.5 已在 Appwrite Cloud 上发布。这个版本备受期待&#xff0c;我们很高兴终于能与大家分享这个好消息。 为了让您快速复习&#xff0c;您现在可以开始使用云计算平台上的…

视频资源汇聚平台常见的几种接入方式

视频资源汇聚平台 视频汇聚平台可以实现海量资源的接入、汇聚、存储、处理、分析、运维等&#xff0c;平台具备轻量化接入能力&#xff0c;可支持多协议方式接入&#xff0c;包括主流标准协议GB28181、RTSP、ONVIF、RTMP、FLV、WEBSOCKET等&#xff0c;以及厂家私有协议与SDK接…

人脸识别之bbox【det_10g】-ncnn(c++)

模型描述 det_10g是insightface 人脸框图和人脸关键点的分类&#xff0c;最终能够得到人脸框图bbox&#xff0c;分值还有人脸五官&#xff08;眼x2、鼻子x1、嘴巴x2&#xff09; 由于我这里没有采用最终结果&#xff0c;通过onnx转换为ncnn&#xff0c;所以后面的步骤结果丢弃…

桌面怎么分类便签 桌面分类便签设置方法

桌面便签&#xff0c;一直是我工作和学习的好帮手。每当灵感闪现或是有待办事项&#xff0c;我都会随手记录在便签上&#xff0c;它们就像我桌面上的小助手&#xff0c;时刻提醒我不要遗漏任何重要事务。 但便签一多&#xff0c;管理就成了问题。一张张五颜六色的便签贴满了我…

autolabor(ROS开发笔记)__1

视频链接&#xff1a;ROS机器人 chapter 1 ROS概述与环境搭建 学习步骤&#xff1a; 1.了解该模块的相关概念 是什么&#xff0c;为什么学&#xff0c;前世今生&#xff0c;发展前景 2.安装官方软件包 具备基本的开发环境&#xff0c;简陋notepad 3.搭建集成开发环境(IDE,Int…

信息检索(35):LEXMAE: LEXICON-BOTTLENECKED PRETRAINING FOR LARGE-SCALE RETRIEVAL

LEXMAE: LEXICON-BOTTLENECKED PRETRAINING FOR LARGE-SCALE RETRIEVAL 标题摘要1 引言2 相关工作3 LEXMAE&#xff1a;词典瓶颈屏蔽自动编码器3.1 语言建模编码器3.2 词典瓶颈模块3.3 弱化掩蔽式解码器3.4 词汇加权检索器的预训练目标和微调 4 实验4.1 主要评估4.2 效率分析与…

[算法][单调栈] [leetcode]316. 去除重复字母

去除重复字母 给你一个字符串 s &#xff0c;请你去除字符串中重复的字母&#xff0c;使得每个字母只出现一次。需保证 返回结果的 字典序最小&#xff08;要求不能打乱其他字符的相对位置&#xff09;。 字典序最小&#xff1a; 考虑字符串 a 与 字符串 b&#xff0c;如果字…

JavaWeb:VsCode创建Web项目

一、Tomcat 先在官网上下载tomcat&#xff0c;解压到自己设定的文件夹。 配置环境变量 path变量配置 系统变量配置 验证服务器开机 二、Maven Maven 是一个基于 Java 的项目管理工具&#xff0c;可以对 Java 项目进行构建、依赖管理&#xff0c;可以自动下载所需要的包&#x…

关于各类软件下载及使用

文章目录 一、VS Code1、下载2、安装3、使用 二、Dev-C1、下载2、安装3、使用 三、VS20191、下载2、安装3、使用 四、IDEA1、下载2、安装3、使用 五、Fiddler1、下载1.1 官网下载1.2 文件下载 2、安装3、使用 一、VS Code 1、下载 2、安装 3、使用 二、Dev-C 1、下载 2、…

【蚂蚁笔试题汇总】2024-05-11-蚂蚁春招笔试题-三语言题解(CPP/Python/Java)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新蚂蚁近期的春秋招笔试题汇总&#xff5e; &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f49…

《超越代码生成:Agentic Reasoning探索研发智能化》——【研发效能·创享大会】

【研发效能创享大会】是由IDCF社区独家举办&#xff0c;这个会议主要聚焦于技术和研发管理&#xff0c;旨在为社区成员提供一个学习与交流的平台&#xff0c;分享技术经验&#xff0c;交流行业见解&#xff0c;促进技术合作与创新&#xff0c;发现并培养人才&#xff0c;推动软…

新能源汽车动力电池浸没式冷却方案介绍与未来趋势

前言 新能源汽车的兴起标志着汽车工业的一次革命&#xff0c;其中动力电池的设计与性能成为了关键。浸没式冷却方案作为一种新兴的技术&#xff0c;为动力电池系统提供了有效的散热解决方案&#xff0c;其在未来的发展趋势备受关注。 一 动力电池浸没式冷却方案介绍 首先&am…

攻防世界-web-command_execution

题目&#xff1a; 原理&#xff1a; | 的作用为将前一个命令的结果传递给后一个命令作为输入 &&的作用是前一条命令执行成功时&#xff0c;才执行后一条命令 方法一&#xff1a; 第一步&#xff1a; 1.打开浏览器&#xff0c;在文本框内输入127.0.0.1 | find / -name…

Qt : 一个超高人气的Node编辑器

真的是很不错的Node编辑器开源项目&#xff0c;基于Qt的图元/场景/视图框架&#xff0c;能做点啥不用我多说。 git地址&#xff1a;https://github.com/paceholder/nodeeditor

分布式链路追踪 Zipkin+Sleuth(8)

项目的源码地址 Spring Cloud Alibaba 工程搭建&#xff08;1&#xff09; Spring Cloud Alibaba 工程搭建连接数据库&#xff08;2&#xff09; Spring Cloud Alibaba 集成 nacos 以及整合 Ribbon 与 Feign 实现负载调用&#xff08;3&#xff09; Spring Cloud Alibaba Ribbo…