【算法】堆与优先级队列
【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();*/
相关文章:

【算法】堆与优先级队列
【ps】本篇有 4 道 leetcode OJ。 目录 一、算法简介 二、相关例题 1)最后一块石头的重量 .1- 题目解析 .2- 代码编写 2)数据流中的第 K 大元素 .1- 题目解析 .2- 代码编写 3)前K个高频单词 .1- 题目解析 .2- 代码编写 4…...
Java基础尚硅谷85-面向对象特征一:封装性
曾国藩说,基础不牢,很难走得远。 所以时时回顾一下Java基础,打好地基,让自己走得更稳,更远。 今天这节课,学到对自己有点价值的东西是: 为什么要封装?保护数据安全。只对外暴露极少…...

828华为云征文 | 将Vue项目部署到Flexus云服务器X实例并实现公网访问
一、Flexus云服务器X实例简介 1.1 概述 华为云Flexus X实例是华为云推出的一款创新云服务器产品,它主要面向中小企业和开发者,旨在解决传统云服务中的痛点,提供更加灵活、高效的云服务体验。 华为深刻洞察了中小企业和开发者在云服务应用中遇…...

828华为云征文|华为云Flexus云服务器X实例部署Xnote笔记应用
828华为云征文|华为云Flexus云服务器X实例部署Xnote笔记应用 前言一、Flexus云服务器X实例介绍1.1 Flexus云服务器X实例简介1.2 Flexus云服务器X实例特点1.3 Flexus云服务器X实例使用场景 二、Note Mark 介绍2.1 Xnote简介2.2 Xnote特点2.3 主要使用场景 三、本次实…...

手写数字识别案例分析(torch,深度学习入门)
在人工智能和机器学习的广阔领域中,手写数字识别是一个经典的入门级问题,它不仅能够帮助我们理解深度学习的基本原理,还能作为实践编程和模型训练的良好起点。本文将带您踏上手写数字识别的深度学习之旅,从数据集介绍、模型构建到…...

应用密码学第一次作业(9.23)
一、Please briefly describe the objectives of information and network security,such as confidentiality, integrity, availability , authenticity , and accountability The objectives of information and network security include: Confidentiality: Protecting se…...
JSON合并工具
JSON合并工具 1. 项目概述 本项目旨在开发一个强大而灵活的JSON合并工具,能够合并多个JSON文件,处理复杂的嵌套结构,提供详细的合并报告,并实现全面的验证和错误处理机制。 2. 功能需求 2.1 基本合并功能 支持合并两个或多个…...
【网络编程】网页的显示过程
文章目录 1.URL 解析2.DNS 解析3.TCP三次握手4.服务器接收请求5.客户端接收响应 首先我们知道网页经过网络总共有应用层,传输层,网络层,数据链路层,物理层 1.URL 解析 将获得的网址解析出协议,主机名,域名…...

用nginx-rtmp-win32-master及ffmpeg模拟rtmp视频流
效果 使用nginx-rtmp-win32-master搭建RTMP服务 双击exe就可以了。切记整个目录不能有中文 README.md ,启用后本地的RTM路径: rtmp://192.168.1.186/live/xxx ffmpeg将地本地视频推RMTP F:\rtsp\ffmpeg-7.0.2-essentials_build\bin>ffmpeg -re -i F:\rtsp\123.mp4 -c c…...
使用python-pptx将PPT转换为图片:将每张幻灯片保存为单独的图片文件
哈喽,大家好,我是木头左! 本文将详细介绍如何使用python-pptx将PPT的每一张幻灯片保存为单独的图片文件。 安装python-pptx库 需要确保已经安装了python-pptx库。可以通过以下命令使用pip进行安装: pip install python-pptx导入所需库 接下来,需要导入一些必要的库,包…...

聊聊企业的低代码实践背景与成效
数字化转型的道路充满挑战是大家的普遍共识,许多企业仍未完全步入数字化的行列,它们面临的是系统的碎片化和操作的复杂性。在数字优先的今天,企业要想维持竞争力,比任何时期都更需要实施某种程度的数字化升级。如果一个组织难以提…...
zookeeper面试题
1. 什么是zookeeper zookeeper是一个开源的 分布式协调服务。他是一个为分布式应用提供一致性服务的软件,分布式应用程序可以基于Zookeeper实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。 Zooke…...

Linux学习笔记13---GPIO 中断实验
中断系统是一个处理器重要的组成部分,中断系统极大的提高了 CPU 的执行效率,本章会将 I.MX6U 的一个 IO 作为输入中断,借此来讲解如何对 I.MX6U 的中断系统进行编程。 GIC 控制器简介 1、GIC 控制器总览 I.MX6U(Cortex-A)的中断控制器…...

[Redis][Hash]详细讲解
目录 0.前言1.常见命令1.HSET2.HGET3.HEXISTS4.HDEL5.HKEYS6.HVALS7.HGETALL8.HMGET9.HLEN10.HSETNX11.HINCRBY12.HINCRBYFLOAT 2.内部编码1.ziplist(压缩链表)2.hashtable(哈希表) 3.使用场景4.缓存方式对比1.原⽣字符串类型2.序列化字符串类型3.哈希类型 0.前言 在Redis中&am…...

上半年亏损扩大/百亿资产重组终止,路畅科技如何“脱困”?
在智能网联汽车市场形势一片大好的前提下,路畅科技上半年的营收却出现了下滑,并且亏损也进一步扩大。 2024年半年度报告显示,路畅科技营业收入1.35亿元,同比下滑7.83%;实现归属上市公司股东的净利润为亏损2491.99万元…...
协议IP规定,576字节和1500字节的区别
576字节和1500字节的区别主要在于它们是IP数据报在数据链路层中的最大传输单元(MTU)的不同限制。 576字节:这个数值通常与IP层(网络层)的数据报有关,它指的是在不进行分片的情况下,IP数据…...

对抗攻击的详细解析:原理、方法与挑战
对抗攻击的详细解析:原理、方法与挑战 对抗攻击(Adversarial Attack)是现代机器学习模型,尤其是深度学习模型中的一个关键安全问题。其本质在于,通过对输入数据添加精微的扰动,人类难以察觉这些扰动&#…...

Python办公自动化教程(003):PDF的加密
【1】代码 from PyPDF2 import PdfReader, PdfWriter# 读取PDF文件 pdf_reader PdfReader(./file/Python教程_1.pdf) pdf_writer PdfWriter()# 对第1页进行加密 page pdf_reader.pages[0]pdf_writer.add_page(page) # 设置密码 pdf_writer.encrypt(3535)with open(./file/P…...

python全栈学习记录(十七)logging、json与pickle、time与datatime、random
logging、json与pickle、time与datatime、random 文章目录 logging、json与pickle、time与datatime、random一、logging二.json与pickle三.time与datatime四.random 一、logging logging模块用来记录日志信息。 import logging # 进行基本的日志配置 logging.basicConfig( fi…...
【艾思科蓝】JavaScript在数据可视化领域的探索与实践
【ACM出版 | EI快检索 | 高录用】2024年智能医疗与可穿戴智能设备国际学术会议(SHWID 2024)_艾思科蓝_学术一站式服务平台 更多学术会议请看 学术会议-学术交流征稿-学术会议在线-艾思科蓝 目录 引言 JavaScript可视化库概览 D3.js基础入门 1. 引入…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...