【算法】堆与优先级队列

【ps】本篇有 4 道 leetcode OJ。

目录

一、算法简介

二、相关例题

1)最后一块石头的重量

.1- 题目解析

.2- 代码编写

2)数据流中的第 K 大元素

.1- 题目解析

.2- 代码编写

3)前K个高频单词

.1- 题目解析

.2- 代码编写

4)数据流的中位数

.1- 题目解析

.2- 代码编写


 

一、算法简介

        普通队列的特点是先进先出,元素在队尾入队,而从队首出队。优先级队列则不同,队列中的每个元素都被赋予了一个权值,权值较高的元素排在最前优先出队。它一般默认通过一个大根堆(即权值以从高到低排列)实现,表现为一个以 vector 为底层的完全二叉树。

        优先级队列常与模拟算法一起出题。除了要掌握如何对优先级队列建大根堆或小根堆,还要能够不借助 STL 提供的优先级队列来自己实现堆这种数据结构,因为这是面试场上常考的(欲知堆的更多细节,请见【数据结构】树之二叉树)。

二、相关例题

1)最后一块石头的重量

1046. 最后一块石头的重量

.1- 题目解析

        对于从一个序列中选出最大值,不难想到堆排序和优先级队列。我们可以将数组中的元素全部插入优先级队列中,然后依此从堆顶取两个元素进行“粉碎”,这两个元素其中一个一定是当前数组中最大的,另一个一定是次大的。如果它们两个相等,就不作处理,相当于两个都“粉碎”了;如果不相等,就将它们的差值入队......以此类推,直至优先级队列中没有元素或仅剩一个元素。

.2- 代码编写

class Solution {
public:int lastStoneWeight(vector<int>& stones) {priority_queue<int> heap;for(auto x:stones)heap.push(x);while(heap.size()>1){int a=heap.top();heap.pop();int b=heap.top();heap.pop();if(a>b)heap.push(a-b);}return heap.size()?heap.top():0;}
};

2)数据流中的第 K 大元素

703. 数据流中的第 K 大元素

.1- 题目解析

        这是一道典型的 Top-K 问题,其解决方法有堆排序、基于快排的快速选择算法。尽管快速选择算法的时间复杂度为 O(n),堆排序为 O(n*logK),但面对海量数据时,快速选择算法的空间复杂度颇高,因此此处选用更优的堆排序来解题。

        具体方式是,创建一个大小为 k 的堆,如果是找第 k 大(排降序)就创建小根堆,找第 k 小(排升序)就创建大根堆。然后将待排序的元素依此进堆,每次进堆都判断一下堆的大小是否超过 k,如此,堆顶存放的就一直是第 k 大或第 k 小的元素。

.2- 代码编写

class KthLargest {priority_queue<int,vector<int>,greater<int>> heap;//排降序建小根堆int _k;
public://显示的构造函数KthLargest(int k, vector<int>& nums) {_k=k;for(auto x:nums){//先将元素入堆进行排序heap.push(x);//堆的大小超过k,就把堆顶元素取出,只留下第k大的元素在堆顶if(heap.size()>_k)heap.pop();}}int add(int val) {heap.push(val);if(heap.size()>_k)heap.pop();return heap.top();}
};/*** Your KthLargest object will be instantiated and called as such:* KthLargest* obj = new KthLargest(k, nums);* int param_1 = obj->add(val);*/

3)前K个高频单词

692. 前K个高频单词

.1- 题目解析

        这也是一道典型的 Top-K 问题。在进行堆排序找到前 k 个高频单词之前,我们需要先对数组中的单词出现的频次进行统计,这样才能进行堆排序。

        而特别的,一般情况下应按单词出现频率由高到低排序,此时应建小堆;当不同的单词有相同频次时, 就要按字典序来排序,此时应建大堆。那么,我们就需要对建堆的排序函数进行特殊处理。

        由于堆顶存放的是频次前 k 大中频次最小的单词,因此从堆顶依此取元素并插入到数组中的时候,需要将元素从后往前插入到数组中,或者从前往后插入,最终将数组逆序。

.2- 代码编写

class Solution {typedef pair<string,int> PSI;struct cmp{bool operator()(const PSI& a,const PSI& b){if(a.second==b.second)return a.first<b.first;return a.second>b.second;}};
public:vector<string> topKFrequent(vector<string>& words, int k) {//1.用哈希表统计频次unordered_map<string,int> hash;for(auto&s:words)hash[s]++;//2.建堆priority_queue<PSI,vector<PSI>,cmp> heap;for(auto& x:hash){heap.push(x);if(heap.size()>k)heap.pop();}//3.统计结果vector<string> ret(k);for(int i=k-1;i>=0;i--){ret[i]=heap.top().first;heap.pop();}return ret;}
};

4)数据流的中位数

295. 数据流的中位数

.1- 题目解析

        要找到一个中位数,这个数据序列必须是有序的。我们可以将一个排好序的序列一分为二,将序列左边的所有元素放入大根堆里,将序列右边的所有元素放入小根堆里,如此,大根堆的堆顶就是序列左边的最大元素,小根堆的堆顶就说序列右边的最小元素,此时只要把这两个堆顶元素相加除以 2,就能得到整个序列的中位数了。

        设 num 是一个待插入堆的元素,m 为序列左边的元素个数,n 为序列右边的元素个数,则:

.2- 代码编写

class MedianFinder {priority_queue<int> left;priority_queue<int,vector<int>,greater<int>> right;
public:MedianFinder() {}void addNum(int num) {if(left.size()==right.size()){if(left.empty()||num<=left.top()){left.push(num);}else{right.push(num);int rightTop=right.top();right.pop();left.push(rightTop);}}else if(left.size()==right.size()+1){if(num<=left.top()){left.push(num);int leftTop=left.top();left.pop();right.push(leftTop);}else {right.push(num);}}}double findMedian() {if(left.size()==right.size())return (left.top()+right.top())/2.0;else return left.top();}
};/*** Your MedianFinder object will be instantiated and called as such:* MedianFinder* obj = new MedianFinder();* obj->addNum(num);* double param_2 = obj->findMedian();*/

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

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

相关文章

怎么操作使http变成https访问?

获取SSL证书 选择证书颁发机构&#xff1a;可以选择受信任的免费或付费证书颁发机构&#xff08;CA&#xff09;如JoySSL 申请和验证域名&#xff1a;注册并填写注册码230920&#xff0c;验证域名所有权。下载SSL证书文件到本地电脑. JoySSL品牌证书 注册享大额优惠JoySSL是网…

数据结构——二叉树堆的专题

1.堆的概念及结构 如果有一个关键码的集合K {K0 &#xff0c;K1 &#xff0c;K2 &#xff0c;K3…&#xff0c;K(N-1) }&#xff0c;把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中&#xff0c;并满足&#xff1a;Ki < K2*i1且 Ki<K2*i2 ) i 0&#…

MICROLAB电源维修MXP7U 400-60 高压电源维修

法国MICROLAB POWER SUPPLY全系列型号电源维修MXP 1500-10。 专注维修进口设备电源&#xff0c;主要有高压电源&#xff08;High Power Supply&#xff09;、框架式可控大功率直流电源&#xff08;DC Power Supply&#xff09;、射频电源(RF Generator)、微波发生器(Microwave…

制作京东首页右侧固定层

html部分 <!DOCTYPE html> <html> <head lang"en"><meta charset"UTF-8"><title>京东首页右侧固定层</title><link href"css/nav.css" rel"stylesheet"> </head> <body> <…

猎板PCB:精密多层板压合定制工艺,打造高性能电路板解决方案

在多层板PCB的制造过程中&#xff0c;压合定制工艺是确保电路板性能和可靠性的关键环节。以下是对猎板PCB多层板压合定制工艺的详细介绍和优化&#xff1a; 选材与预处理&#xff1a; 精选高品质基材&#xff0c;如FR-4&#xff0c;确保机械和电气性能。对铜箔进行彻底清洁、微…

解决猫咪缺水难题!主食罐应该多久喂一次?补水主食罐推荐

我们家猫咪以猫粮为主食&#xff0c;但每周至少要喂2——3个主食猫罐头。这是因为猫粮的水含量低&#xff0c;加上猫咪习惯从猎物中获取所水分&#xff0c;很少主动喝水&#xff0c;只喂猫粮的话&#xff0c;猫咪容易因为补水不足而患上泌尿系统疾病、肾脏等问题。而主食罐头的…

【经典文献】双边曲面去噪

文章目录 2003 TOG基本思想效果 2003 TOG 2003年&#xff0c;Fleishman等人在TOG上&#xff0c;基于图像双边滤波的思想&#xff0c;将其改造成了可以用在曲面上的双边滤波算法。 Fleishman S, Drori I, Cohen-Or D. Bilateral mesh denoising[M]//ACM SIGGRAPH 2003 Papers.…

YOLOv9改进策略【卷积层】| AKConv: 具有任意采样形状和任意参数数量的卷积核

一、本文介绍 本文记录的是利用AKConv优化YOLOv9的目标检测网络模型。标准卷积操作的卷积运算局限于局部窗口&#xff0c;无法捕获其他位置的信息&#xff0c;且采样形状固定&#xff0c;无法适应不同数据集和位置中目标形状的变化。而AKConv旨在为卷积核提供任意数量的参数和…

LeetCode[中等] 438. 找到字符串中所有字母异位词

给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 思路&#xff1a;滑动窗口 s包含p的异位词 ——> 则…

静态住宅代理 vs 住宅代理:稳定IP有哪些优势?

在代理服务器中&#xff0c;我们通常以IP地址是否经常轮换为标准&#xff0c;将代理分为静态和住宅代理。这两种代理方式各有千秋&#xff0c;在不同的应用场景中发挥着不同的作用。但是由于场景繁多&#xff0c;用处也大有不同&#xff0c;导致很多人对于这两种代理方式并不是…

基于微信小程序的游泳馆管理系统--论文源码调试讲解

2 关键技术介绍 2.1 SSM框架 开发信息管理系统的主流框架是SSM&#xff08;Spring Spring MVC MyBatis&#xff09;&#xff0c;SSM框架web层使用Spring MVC框架&#xff0c;使传输前后端数据变得简单&#xff1b;对于业务层使用Spring作为轻量级控制反转和面向切面的容器框…

C++速通LeetCode中等第5题-无重复字符的最长字串

字串substr法&#xff0c;定义字串的头部和长度&#xff0c;和字串后一位对比&#xff0c;如果不存在重复元素则长度1&#xff0c;存在重复元素则头部更新&#xff0c;长度重置。 class Solution { public:int lengthOfLongestSubstring(string s) {string s2;//存放s的前一部分…

springboot实训学习笔记(4)(Spring Validation参数校验框架、全局异常处理器)

接着上篇博客学习。上篇博客是已经基本完成用户模块的注册接口的开发。springboot实战学习笔记&#xff08;3&#xff09;(Lombok插件、postman测试工具、MD5加密算法、post请求、接口文档、注解、如何在IDEA中设置层级显示包结构、显示接口中的方法)-CSDN博客本篇博客主要是关…

【free -h内存占用】

在 free -g 命令的输出中&#xff0c;最能准确反映系统中剩余可用内存的参数是 available。这个参数考虑了缓存和缓冲的内存&#xff0c;可以更准确地反映系统的可用内存。 让我们再看一下假设的输出&#xff1a; total used free shared buff/cache av…

【PGCCC】使用 Postgres 进行数据分析的窗口函数

SQL 在处理单行数据时&#xff0c;甚至在聚合多行数据时都很有意义。但是&#xff0c;当您想比较已计算的行之间的数据时会发生什么&#xff1f;或者创建数据组并进行查询&#xff1f;输入窗口函数。 窗口函数往往会让人感到困惑 - 但它们是 SQL 中用于数据分析的非常棒的工具…

实验2 Linux文件系统常用操作实践

实验2 Linux文件系统常用操作实践 一、实验介绍 本节实验通过实战Linux文件操作模块的基本操作,需要先掌握linux文件系统的原理以及理解linux文件操作的原理,最后通过实操完成linux文件操作的命令,其中包括改变目录、创建目录及文件、删除文件、复制文件、文件移动和改名、查…

【大模型入门】零基础入门AI大模型应用开发,你需要一个系统的入门路径!

随着大模型技术的飞速发展&#xff0c;我们正站在一个全新的技术前沿&#xff0c;探索着如何将这些强大的工具应用于实际问题的解决。如果你对AI大模型应用开发充满热情&#xff0c;那么你可以读一下这篇文章——一个系统全面的入门指南&#xff0c;专为渴望深入AI世界的你设计…

Windows 系统管理

1 安装 Windows Server 2016 操作系统的硬件最低需求&#xff1f; 处理器 1.4GHz 64 位处理器 RAM 512MB&#xff08;带桌面体验 2GB&#xff09; 磁盘空间 32GB 2 Windows Server 2016 操作系统的常见版本&#xff1f; Windows Server 2016 Standard&#xff08; 标 准 版 &a…

【新手必看】SpringBoot集成Minio实现文件上传、下载和删除

一&#xff0c;前言 安装教程可看我以前的文章&#xff0c;Linux和Windows安装教程都有。安装好minio后今天学习minio的使用。 二&#xff0c;集成Minio 1&#xff0c;导入依赖&#xff0c;版本可自己选择 <!-- https://mvnrepository.com/artifact/io.minio/minio -->…

LeetCode力扣——并查集:947. 移除最多的同行或同列石头,1971. 寻找图中是否存在路径,2424. 最长上传前缀

947. 移除最多的同行或同列石头 题目描述 947. 移除最多的同行或同列石头 n 块石头放置在二维平面中的一些整数坐标点上。每个坐标点上最多只能有一块石头。 如果一块石头的 同行或者同列 上有其他石头存在&#xff0c;那么就可以移除这块石头。 给你一个长度为 n 的数组 …