【算法优选】优先级队列(堆)的经典应用

Silvaco 学习笔记——物理模型:载流子产生复合模型 对载流子的复合机制进行总结 阅读详情

掌握优先级队列的核心思想,高效解决TopK/中位数等高频算法问题!


一、最后一块石头的重量

问题描述

每次选择最重的两块石头碰撞,若重量相同则消失,不同则留下差值。求最终剩余石头的重量。

示例:
输入:[2,7,4,1,8,1] → 碰撞过程:

  1. 8 vs 7 → 余1 → [2,4,1,1,1]
  2. 4 vs 2 → 余2 → [1,1,1,2]
  3. 2 vs 1 → 余1 → [1,1,1]
  4. 1 vs 1 → 消失 → 最终结果:1

解题思路

  1. 大顶堆存储:将所有石头放入大顶堆(Java的PriorityQueue默认小顶堆,需重写比较器)
  2. 循环碰撞:每次弹出堆顶两个元素进行碰撞
  3. 差值入堆:若碰撞后剩余重量>0,将差值重新入堆
  4. 终止条件:堆中元素≤1时停止

代码实现

class Solution {
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> heap = new PriorityQueue<>((a, b) -> b - a); // 大顶堆
        for (int stone : stones) heap.offer(stone);
        
        while (heap.size() > 1) {
            int y = heap.poll(); // 最重石头
            int x = heap.poll(); // 次重石头
            if (y > x) heap.offer(y - x); // 碰撞后剩余
        }
        return heap.isEmpty() ? 0 : heap.peek();
    }
}

二、数据流中的第 K 大元素

问题特点

  • 动态数据流:持续添加新元素
  • 实时获取当前第K大的元素

解决方案:小顶堆维护TopK

  1. 初始化:创建大小为K的小顶堆
  2. 添加元素:
    • 堆未满时直接入堆
    • 堆满后,若新元素>堆顶则替换堆顶
  3. 获取结果:堆顶即第K大元素

复杂度分析

  • 时间复杂度:add()操作O(log⁡K)O(\log K)O(logK),get()操作O(1)O(1)O(1)
  • 空间复杂度:O(K)O(K)O(K)
class KthLargest {
    private final PriorityQueue<Integer> minHeap;
    private final int k;

    public KthLargest(int k, int[] nums) {
        this.k = k;
        minHeap = new PriorityQueue<>();
        for (int num : nums) add(num); // 复用添加逻辑
    }
    
    public int add(int val) {
        if (minHeap.size() < k) {
            minHeap.offer(val);
        } else if (val > minHeap.peek()) {
            minHeap.poll();      // 移除堆顶
            minHeap.offer(val);  // 加入新元素
        }
        return minHeap.peek();
    }
}

三、前K个高频单词

双关键排序挑战

  1. 频率降序:出现次数多的在前
  2. 字典序升序:频率相同时按字母顺序排序

解题步骤

  1. 统计频率:HashMap记录单词出现次数
  2. 堆排序:
    • 小顶堆维护TopK(按频率升序/字典序降序)
    • 自定义比较器实现双条件排序
  3. 结果反转:堆中元素弹出后需反转顺序

核心比较器

Comparator<String> comp = (a, b) -> 
    map.get(a).equals(map.get(b)) ? 
        b.compareTo(a) : // 频率相同:按字典序降序(Z->A)
        map.get(a) - map.get(b); // 频率升序

完整代码

class Solution {
    public List<String> topKFrequent(String[] words, int k) {
        Map<String, Integer> map = new HashMap<>();
        for (String word : words) 
            map.put(word, map.getOrDefault(word, 0) + 1);
        
        // 小顶堆:频率升序,字典序降序
        PriorityQueue<String> heap = new PriorityQueue<>(
            (a, b) -> map.get(a).equals(map.get(b)) ? 
                b.compareTo(a) : map.get(a) - map.get(b)
        );
        
        for (String word : map.keySet()) {
            heap.offer(word);
            if (heap.size() > k) heap.poll(); // 维护堆大小
        }
        
        // 反转结果
        LinkedList<String> res = new LinkedList<>();
        while (!heap.isEmpty()) res.addFirst(heap.poll());
        return res;
    }
}

四、数据流的中位数

核心难点

动态数据流中实时获取中位数,需同时支持:

  1. 快速插入:添加新元素
  2. 快速查询:获取当前中位数

双堆平衡策略

数据结构存储内容特点
大顶堆较小的一半数据堆顶是左半段最大值
小顶堆较大的一半数据堆顶是右半段最小值

操作规则

  1. 添加元素:
    在这里插入图片描述

  2. 获取中位数:

    • 总数为奇:大顶堆堆顶
    • 总数为偶:两堆堆顶平均值

代码实现

class MedianFinder {
    private final PriorityQueue<Integer> maxHeap; // 存储较小值
    private final PriorityQueue<Integer> minHeap; // 存储较大值

    public MedianFinder() {
        maxHeap = new PriorityQueue<>((a, b) -> b - a); 
        minHeap = new PriorityQueue<>();
    }
    
    public void addNum(int num) {
        // 选择插入堆
        if (maxHeap.isEmpty() || num <= maxHeap.peek()) {
            maxHeap.offer(num);
        } else {
            minHeap.offer(num);
        }
        
        // 平衡堆大小
        if (maxHeap.size() > minHeap.size() + 1) {
            minHeap.offer(maxHeap.poll());
        } else if (minHeap.size() > maxHeap.size()) {
            maxHeap.offer(minHeap.poll());
        }
    }
    
    public double findMedian() {
        if (maxHeap.size() > minHeap.size()) {
            return maxHeap.peek();
        }
        return (maxHeap.peek() + minHeap.peek()) / 2.0;
    }
}

复杂度分析

操作时间复杂度空间复杂度
添加元素O(log⁡N)O(\log N)O(logN)O(N)O(N)O(N)
查询中位数O(1)O(1)O(1)-

堆的本质是部分有序的结构化思维,在动态数据场景中,它能以最低成本维护关键有序信息。掌握这四类经典问题,即可解决90%优先级队列相关算法题!

Axial Attention 和 Criss-Cross Attention及其代码实现 Axial Attention 和 Criss-Cross Attention及其代码实现 ​ 文章目录Axial Attention 和 Criss-Cross Attention及其代码实现1 Criss - Cross Attention介绍1.1 引言1.2 理论实现1.2.1 获取权重A1.2.2 Affinity操作1.3.3 全部信息获取1.3 代码实现1.3.1 官方实现1.3.2 纯pytorch实现2 Axial Attention 介绍2.1 引言2.2 理论实现2.3 代码实现2.3 阅读详情

相关推荐

ANSYS 有限元分析 支架拓扑优化设计 分析过程及常见问题解决

1.确定分析类型,所用模块包括两种 static structural Topology Optimization。3.通过草图建立几何模型,建好的几何模型如图1所示。2.工程材料采用默认的Q235。

m0_68737530的博客 1968

对顶堆(或小根堆) -> “第K大的元素”问题

对顶堆由一个大根堆G和一个小根堆L构成,且常以小根堆L的堆顶元素L.top()作为对顶堆的分界点,并满足G.top()<L.top()。换句话表述,就是“在对顶堆中,大根堆的元素都小于L.top(),小根堆的元素都大于L.top()”。显然,若输入的元素大于L.top(),就加入小根堆。反之,就加入大根堆。

hnjzsyjyj的专栏 2006

Ubuntu无桥接模式或连不上网(详细解决方法

目录 问题1:Ubuntu没有未桥接的主机网络适配器 解决方法 1.打开VMware安装目录下的文件 ​编辑2.右键安装以上三个文件 3.打开网络状态属性,找到VMware bridgeProtocol,点击安装 问题2.Ubuntu桥接模式连不上网 1.win+r打开cmd终端,输入ipconfig /all 2.记录以下数据 3.打开VMware网络设置 问题1:Ubuntu没有未桥接的主机网络适配器 VMWare安装之后,虚拟网络一直使用默认配置 VMnet0为...

m0_65592409的博客 6062

【算法】【优选算法】优先级队列

堆在算法题中的使用

yj20040627的博客 2万+

从AMBA到USB:手把手教你评估和选择Synopsys DesignWare里的免费商用IP

本文详细介绍了如何评估和选择Synopsys DesignWare中的免费商用IP,从AMBA到USB等关键模块。通过技术参数核对、验证环境评估和集成注意事项,帮助工程师高效利用这些经过硅验证的商业级IP,提升SoC设计效率。文章还探讨了免费IP与付费IP的边界策略,避免常见陷阱。

weixin_42683394的博客 299

Visionpro 使用CogPMAlignTool工具提取匹配轮廓点

【代码】Visionpro 使用CogPMAlignTool工具提取匹配轮廓点。

weixin_43947315的博客 2093

【优选算法】优先级队列(堆)

本篇文章列举了四个经典的LeetCode算法题目,包括最后一块石头的重量、数据流中的第K大元素、前K个高频单词和数据流的中位数。我会在每道题中提到每道题的解题思路,并提供解决本题的C++代码,希望通过这些题的讲解,能够加深大家对优先级队列的理解。

是阿建吖! 1945

PAM4信号测试实战:从眼图分析到误码率测量的技术演进

在高速数字系统设计中,信号完整性测试是确保数据传输可靠性的核心环节。其基本原理在于通过时域和频域分析,精确评估信号在传输过程中的质量衰减与失真。随着数据速率向56Gbps及以上演进,传统的NRZ编码面临带宽瓶颈,而PAM4调制技术通过在每个符号周期内承载更多比特信息,成为提升信道效率的关键路径。这项技术的工程价值在于,它允许在相同带宽下实现翻倍的数据吞吐量,这对于数据中心互联、PCIe 6.0及800G以太网等高速接口至关重要。然而,PAM4信号电平间距更小,对噪声和抖动极为敏感,导致其原始误码率显著升高,

weixin_42522817的博客 660

【优选算法 | 优先级队列】从堆实现到解题框架:彻底搞懂优先级队列

优先级队列(Priority Queue),本质上是一个支持动态插入与按优先级弹出操作的堆结构,是处理这类问题的强力工具。 本文将从底层的堆实现出发,逐步构建出优先级队列的完整解题框架,并结合高频 题目,帮助你真正掌握它在算法实战中的运用。

专注于 C/C++ 后端开发,涵盖基础语法、Linux系统与网络、MySQL数据库、常见算法及项目经验。 1894

TC3xx系列LMU与SPR实战:将关键算法从Flash搬移至PSPR提升5倍执行效率

在实际电机控制项目中,通过将FOC算法全部迁移到PSPR,我们不仅将执行时间从56μs降至11μs,还将最坏情况下的时间偏差控制在±0.3μs以内。实测数据:在TC397上执行Flash中的32位浮点矩阵乘法,平均每条指令需要8.7个周期,而同样的代码在PSPR中仅需1.2个周期。传统开发中,工程师往往将所有代码放在Flash中运行,这相当于让F1赛车在乡村公路上行驶。迁移后不仅平均执行时间缩短,更重要的是时间抖动从±15%降低到±2%以内,这对闭环控制系统至关重要。不是所有代码都适合迁移到PSPR。

weixin_31421613的博客 299

Android 13 内置xapk安装包的方法

安装xapk 内置xapk

安卓兼职framework和app工程师的博客 226

优选算法——优先级队列

💁‍♂️👇。

2501_93697341的博客 848

基于Simulink的双向DC-DC变换器在储能系统中的应用仿真

摘要:本文详细介绍了基于Simulink的双向DC-DC变换器在光伏储能系统中的仿真实现。主要内容包括:1)采用非隔离型双向Buck-Boost拓扑作为储能系统枢纽;2)针对750V直流微网中的20kWh锂电池接口场景进行建模;3)详细阐述双闭环控制器设计(电压外环+电流内环)、工作模式判断逻辑等关键步骤;4)通过仿真验证了系统在功率阶跃和模式切换下的性能。文章提供了完整的建模流程和控制方法,为储能系统接口设计提供了实用参考。

amy_mhd的博客 180

C++优选算法十四 优先级队列(堆)

C++ 中的优先级队列(Priority Queue)是一种容器适配器,它提供队列的功能,但元素不是按照插入的顺序被访问,而是根据它们的优先级被访问。

m0_74826386的博客 1586

贝叶斯统计 [韦来生编]

贝叶斯(Bayes)统计是近几十年来迅速发展起来的数理统计的一个重要分支。贝叶斯方法与经典统计方法的主要不同之处是进行统计推断时除了利用样本信息外,还要利用参数的先验信息,因此可以提高统计推断或统计决策的效果。它在经济、金融、生物、医学、自然科学和社会科学等许多领域具有广泛的应用。贝叶斯方法的研究已渗透到了统计学的几乎所有领域。作者在给中国科学技术大学概率论与数理统计专业本科生开设的“数理统计”课程中有一章专门讲授“贝叶斯方法和统计决策理论”,近十年来也给中国科学技术大学概率统计专业研究生开设过几次“贝叶斯分析”课。本书是在对过去讲稿的内容作了适当的增减和调整的基础上完成的。  本书共分六章。第1章是绪论,介绍了贝叶斯统计的若干基本概念,同时对必要的数理统计的基础知识有重点地作了回顾。第二章介绍了确定先验分布的若干可供选择的方法。第三章介绍了几类常见统计模型参数的后验分布的主要结果和计算方法。第四章和第五章分别介绍了“贝叶斯统计推断”和“贝叶斯统计决策”的内容。第六章介绍了贝叶斯统计计算的若干方法,包括蒙特卡洛方法和马尔可夫链蒙特卡洛(MCMC)方法以及相关统计软件的简介。本书的每一章附右大量的例题和习题,书末附有常用的几个表格和部分习题解答供读者查用。  大约可在54学时内讲授本书的第1章至第六章的主要内容,教师可根据学时需要选讲本书第1章至第六章的部分内容。书中标“*”号的章节可略去不讲,留给读者作为阅读材料。第六章例题中的R代码和部分例题的数据文件等可从作者个人主页下载。  作者在编写本书的过程中参考了J.O.Berger教授的《统计决策论及贝叶斯分析》和茆诗松教授编写的《贝叶斯统计》等书中的一些内容,以及《贝叶斯分析》一书中由张伟平博士编写的有关贝叶斯统计计算的一些内容。在此表示衷心感谢。  本书编写准备过程中,中国科学技术大学统计与金融系的几个研究生帮助完成了本书部分中文的录入和排版,作者对他们的辛勤工作表示真诚的感谢。高等教育出版社为本书的出版给予了大力支持。在此一并致谢。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【优选算法】(实战:栈、队列、优先级队列高频考题通关全解)

本文摘要: 本文系统讲解了栈、队列和优先级队列三大基础数据结构的实战应用。通过LeetCode经典题目《删除相邻重复项》和《含退格字符串比较》的解析,展示了栈结构在字符串处理中的典型应用场景。文章采用"原理-模板-真题"三维教学法,重点剖析了栈的"后进先出"特性如何高效解决相邻元素匹配问题,并提供了完整的C++代码实现与测试案例。针对算法学习者常见的"懂原理不会做题"痛点,文章强调从实际问题出发,帮助大家更好的掌握这些思想方法与底层原理。

承于所学,探技术之渊;以代码求政,寻成长之道。 1万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

优选算法--优先级队列(堆)

本文探讨了优先级队列(堆)的基本原理及其在算法中的应用。首先介绍了堆的概念、分类(大根堆/小根堆)和存储方式,分析了PriorityQueue的特性及其操作的时间复杂度。然后通过四个典型例题展示了堆的实际应用:1)使用大根堆解决"最后一块石头的重量"问题;2)利用小根堆处理"数据流中的第K大元素";3)结合哈希表和堆解决"前K个高频单词"问题;4)通过大小堆配合实现"数据流的中位数"计算。每个问题都详细阐述了算法思路并提供了代码

budingxiaomoli的博客 417

【优选算法】优先级队列 {优先级队列解决TopK问题,利用大小堆维护数据流的中位数}

【优选算法】优先级队列 {优先级队列解决TopK问题,利用大小堆维护数据流的中位数}

52Herzt的博客 1257

【优选算法之队列+宽搜/优先级队列】No.14--- 经典队列+宽搜/优先级队列算法

【优选算法之队列+宽搜/优先级队列】No.14--- 经典队列+宽搜/优先级队列算法

小沈.的博客 1037

优选算法专题13:优先级队列(堆)

解法:模拟大根堆。

yonakaame的博客 203

【优选算法篇】优先级队列(堆/Heap)——极值的瞬间捕获

本文探讨了堆(Heap)在解决动态集合问题中的高效应用,通过四个典型题目展示了堆的核心思路和实现技巧:1)使用大根堆模拟粉碎石头过程;2)用小根堆维护数据流中的第K大元素;3)通过自定义比较器实现多维度排序获取高频单词;4)利用双堆平衡机制高效计算数据流中位数。这些案例揭示了堆在处理实时数据、优先级排序和动态统计中的独特优势,时间复杂度均优化至O(logN)级别。

半截诗的博客~ 452

常见“优先级队列(堆)”相关题目

LeetCode相关刷题

我要学编程的博客 1292

【优选算法】专题十四——优先级队列

本题使用PriorityQueue的方法与以往不同:如果heap大小超过了k,就立即将堆顶元素弹出,最后堆中剩下的就是前k大元素,这个方法的代码实现比较方便,以后可以使用这个哈希表的应用+TopK问题可以注意一下第2点Lambda表达式中的方法主体实现,分别构建了大根堆和小根堆,已经注释中解释的为什么要分别构建了大根堆和小根堆复习解题思路和代码实现及解析。

2502_91380778的博客 515

优选算法-优先级队列(堆):76.前K个高频单词

优选算法-优先级队列(堆):76.前K个高频单词解析

要努力去发光,而不是被照亮~ 377

优选算法第十二讲:队列 + 宽搜 && 优先级队列

优选算法第十二讲:队列 + 宽搜 && 优先级队列

2301_79761834的博客 403

优选算法-优先级队列(堆):75.数据流中的第K大元素

优选算法-优先级队列(堆):75.数据流中的第K大元素解析

要努力去发光,而不是被照亮~ 373

【优选算法】(第三十八篇)

给定⼀个单词列表words和⼀个整数k,返回前k个出现次数最多的单词。"the","is","sunny"和"day"是出现次数最多的四个单词,出现次数依次为4,3,2和1次。频次相同的时候,我们需要的是字典序较⼩的,此时是⼀个⼤根堆的属性,在定义⽐较器的时候需要注意!a. 我们需要知道每⼀个单词出现的频次,因此可以先使⽤哈希表,统计出每⼀个单词出现的频。▪ 当两个字符串出现的频次相同的时候:需要的是基于字典序⽐较的⼤根堆。▪ 当两个字符串出现的频次不同的时候:需要的是基于频次⽐较的⼩根堆。

weixin_73861555的博客 1133

优选算法--链表

本文总结了链表操作的常用技巧和算法实现。主要技巧包括:画图辅助理解、使用虚拟头节点简化操作、定义辅助变量以及快慢双指针应用。文章详细解析了5个典型链表题目:1)两数相加的模拟计算;2)两两交换节点的递归和迭代实现;3)重排链表的三步法;4)合并K个有序链表的优先级队列和分治解法;5)K个一组翻转链表的组数计算和头插法实现。每个题目都包含算法原理分析和完整代码实现,涵盖了链表操作的核心技巧和常见解法模式。

budingxiaomoli的博客 1041
上一篇: 高效工作法则:掌握五大核心管理工具,告别低效内耗!
下一篇: Spring Boot 常用注解整理:提升开发效率的利器
Java_ESS
博客等级 码龄7年 97粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值