2026/4/18 1:34:54
网站建设
项目流程
网站建设工作总结,chinacd.wordpress,做软件的声称发现网站漏洞,成都培训机构排名前十堆#xff08;优先队列#xff09;是一种基于完全二叉树的动态数据结构#xff0c;核心特性是快速获取最值#xff08;大根堆获取最大值#xff0c;小根堆获取最小值#xff09;#xff0c;插入和删除操作的时间复杂度均为 O(logn)O(\log n)O(logn)。它广泛应用于“动…堆优先队列是一种基于完全二叉树的动态数据结构核心特性是快速获取最值大根堆获取最大值小根堆获取最小值插入和删除操作的时间复杂度均为O(logn)O(\log n)O(logn)。它广泛应用于“动态维护最值”“Top-K 问题”“中位数维护”等场景是处理动态数据的高效工具。本文通过4道经典题目拆解堆在不同场景下的解题思路与代码实现。一、最后一块石头的重量题目描述有一堆石头每回合选两块最重的石头粉碎若重量相等则完全粉碎否则剩下重量为两者差值的石头。返回最后剩下的石头重量无剩余则返回0。示例输入stones [2,7,4,1,8,1]输出1粉碎过程8-71→4-22→2-11→1-10→剩1解题思路用大根堆维护石头重量每次取最大的两块处理将所有石头重量入大根堆。当堆中元素数1时取出最大的两块a和ba ≥ b若a b将a - b入堆若a b直接丢弃两块。最终堆中若有元素则返回堆顶否则返回0。完整代码classSolution{public:intlastStoneWeight(vectorintstones){priority_queueintheap;// 大根堆默认for(autox:stones)heap.push(x);while(heap.size()1){intaheap.top();heap.pop();intbheap.top();heap.pop();if(ab)heap.push(a-b);}returnheap.size()?heap.top():0;}};复杂度分析时间复杂度O(nlogn)O(n\log n)O(nlogn)n为石头数量每次入堆/出堆操作时间为O(logn)O(\log n)O(logn)最多执行nnn次。空间复杂度O(n)O(n)O(n)堆存储所有石头重量。二、数据流中的第K大元素题目描述设计一个类动态维护数据流中的第K大元素排序后的第K大非第K个不同元素。实现KthLargest类包含初始化和添加元素后返回第K大的方法。示例初始化k3, nums[4,5,8,2]添加3→返回4添加5→返回5添加10→返回5。解题思路用小根堆维护“前K大的元素”堆顶即为第K大元素初始化时将所有元素入堆若堆大小超过K则弹出堆顶保留前K大的元素。添加元素时将新元素入堆若堆大小超过K则弹出堆顶堆顶即为当前第K大元素。完整代码classKthLargest{int_k;priority_queueint,vectorint,greaterintheap;// 小根堆public:KthLargest(intk,vectorintnums){_kk;for(autox:nums){heap.push(x);if(heap.size()_k)heap.pop();}}intadd(intval){heap.push(val);if(heap.size()_k)heap.pop();returnheap.top();}};复杂度分析初始化时间O(nlogK)O(n\log K)O(nlogK)n为初始元素数每个元素入堆/出堆时间为O(logK)O(\log K)O(logK)。添加元素时间O(logK)O(\log K)O(logK)每次入堆/出堆时间为O(logK)O(\log K)O(logK)。空间复杂度O(K)O(K)O(K)堆最多存储K个元素。三、前K个高频单词题目描述给定单词列表words和整数k返回前K个出现次数最多的单词频率相同按字典序升序排列。示例输入words [i,love,leetcode,i,love,coding], k2输出[i,love]频率均为2字典序i love解题思路哈希表统计频率 小根堆维护前K个高频单词用哈希表统计每个单词的出现频率。定义小根堆的比较规则频率不同时频率小的优先出堆频率相同时字典序大的优先出堆保证堆顶是“频率最小/字典序最大”的候选弹出后保留前K个。遍历哈希表将“单词-频率”入堆若堆大小超过K则弹出堆顶。逆序收集堆中元素因小根堆弹出的是较小的元素需反转得到从大到小的顺序。完整代码classSolution{typedefpairstring,intPSI;structcmp{booloperator()(constPSI a,constPSI b){if(a.secondb.second)returna.firstb.first;// 频率相同字典序大的优先出堆elsereturna.secondb.second;// 频率小的优先出堆}};public:vectorstringtopKFrequent(vectorstringwords,intk){unordered_mapstring,inthash;for(autox:words)hash[x];priority_queuePSI,vectorPSI,cmpheap;for(autopsi:hash){heap.push(psi);if(heap.size()k)heap.pop();}vectorstringret(k);for(intiheap.size()-1;i0;i--){ret[i]heap.top().first;heap.pop();}returnret;}};复杂度分析时间复杂度O(mlogk)O(m\log k)O(mlogk)m为不同单词的数量每个单词入堆/出堆时间为O(logk)O(\log k)O(logk)。空间复杂度O(mk)O(m k)O(mk)哈希表存储所有单词频率堆存储K个单词。四、数据流的中位数题目描述设计一个类动态维护数据流的中位数奇数个元素取中间值偶数个取中间两个的平均值。实现MedianFinder类包含添加元素和获取中位数的方法。示例添加1→添加2→中位数1.5→添加3→中位数2.0解题思路用两个堆维护数据流的左右两部分大根堆left存储左半部分元素≤中位数堆顶为左半部分最大值小根堆right存储右半部分元素≥中位数堆顶为右半部分最小值保持平衡规则总元素数为偶数时left.size() right.size()总元素数为奇数时left.size() right.size() 1中位数为left.top()添加元素时根据元素与堆顶的大小关系选择入堆并调整堆的大小以保持平衡。完整代码classMedianFinder{priority_queueintleft;// 大根堆左半部分priority_queueint,vectorint,greaterintright;// 小根堆右半部分public:MedianFinder(){}voidaddNum(intnum){if(left.size()right.size()){if(left.empty()||numleft.top()){left.push(num);}else{right.push(num);left.push(right.top());right.pop();}}else{if(numleft.top()){left.push(num);right.push(left.top());left.pop();}else{right.push(num);}}}doublefindMedian(){if(left.size()right.size())return(left.top()right.top())/2.0;elsereturnleft.top();}};复杂度分析添加元素时间O(logn)O(\log n)O(logn)每次入堆/出堆时间为O(logn)O(\log n)O(logn)。获取中位数时间O(1)O(1)O(1)直接取堆顶计算。空间复杂度O(n)O(n)O(n)两个堆存储所有元素。