算法笔记(十一)——优先级队列(堆)

news2025/2/3 9:00:58

文章目录

  • 最后一块石头的重量
  • 数据流中的第 K 大元素
  • 前K个高频单词
  • 数据流的中位数

优先级队列是一种特殊的队列,元素按照优先级从高到低(或从低到高)排列,高优先级的元素先出队,可以用 来实现

是一种二叉树的结构,有两种主要类型:最大堆和最小堆
下面附上之前写的两篇博客:
优先级队列(priority_queue)
数据结构堆(Heap)的实现

最后一块石头的重量

题目:最后一块石头的重量

在这里插入图片描述
思路

  • 创建一个大根堆priority_queue<int> pq;默认情况下是大根堆,将所以石头加入到堆中
  • 用一个循环处理,直至堆中元素剩余元素个数小于等于1
  • 依次取出堆顶元素x,y其中x >= y
  • x = y ,则pop掉两元素;
  • x > y,则pop掉两元素,之后将x - ypush进堆
  • 循环结束后,若剩一个元素,即为其重量;若堆为空,则返回0

C++代码

class Solution 
{
public:
    int lastStoneWeight(vector<int>& stones) 
    {
        priority_queue<int> pq; 
        for(auto e : stones) 
            pq.push(e);
        
        while(pq.size() > 1) 
        {
            int x = pq.top();
            pq.pop();
            int y = pq.top();
            pq.pop();

            if (x > y)
                pq.push(x - y);   
        }

        return pq.size() == 0 ? 0 : pq.top();  
    }
};

数据流中的第 K 大元素

题目:数据流中的第 K 大元素

在这里插入图片描述
思路

  • 经典topK问题
  • 创建一个大小为k的堆
  • 循环:依次进堆,判断堆的大小是否超过k

找的是第k大元素,维护一个大小为k的最小堆,保证堆中只有前 k大的元素

  • 将新元素加入最小堆中,然后检查堆的大小是否超过k,如果超过则弹出堆顶元素
    最终返回当前堆顶元素,即为第 k大的元素
  • add 操作后始终保持堆中的元素为前 K 大的元素
  • 而堆顶元素即为第k大的元素。

C++代码

class KthLargest 
{
    // 创建一个大小为 k 的小根堆
    priority_queue<int, vector<int>, greater<int>> heap;
    int _k;
public:
    KthLargest(int k, vector<int>& nums) 
    {
        _k = k;
        for(int& x : nums)
        {
            heap.push(x);
            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);
 */

前K个高频单词

题目:前K个高频单词

在这里插入图片描述
思路

  • 经典topK问题
  • 创建一个大小为k的堆
  • 循环:依次进堆,判断堆的大小是否超过k

找出前k个出现次数最多的,所以整体我们建小堆
对比较函数按照要求实现,不能用库里的;
如果两个字符串出现频率相同,那么我们让两字符串中字典序较小的排在前面,否则我们让出现频率较高的排在前面
C++代码

class Solution 
{
    typedef pair<string, int> PSI;
    struct cmp
    {
        bool operator()(const PSI& x, const PSI& y)
        {
            if(x.second == y.second) return x.first < y.first;
            else return x.second > y.second;
        }
    };
public:
    vector<string> topKFrequent(vector<string>& words, int k) 
    {
        // 统计单词的频次
        unordered_map<string, int> hash;
        for(auto e:words) hash[e]++;
        // 创建一个大小为 k 的堆
        priority_queue<PSI, vector<PSI>, cmp> heap;
        
        for(auto&e:hash)
        {
            heap.push(e);
            if(heap.size() > k) heap.pop();
        }
        // 答案
        vector<string> ret(k);
        for(int i = k - 1; i >= 0; i--)
        {
            ret[i] = heap.top().first;
            heap.pop();
        }
        return ret;
    }
};

数据流的中位数

题目:数据流的中位数

在这里插入图片描述
思路

利用大小堆来维护数据流的中位数

  • 初始化两个优先队列
  • left 用于存放较小的一半元素(大根堆)
  • right 用于存放较大的一半元素(小根堆)
    在这里插入图片描述
  • 个数为偶数时,大根堆元素个数m等于小根堆元素个数n,即m = n
  • 个数为奇数时,大根堆left多放一个,即m = n + 1
  • x,y 分别为大根堆、小根堆堆顶元素

add()添加元素时,我们按照下述方法维护两个堆

  • m == n时,
    • num <= x || m == 0num直接进入left
    • num > x num先进入right堆,再将right堆定元素放入left
  • m == n + 1时,
    • num <= xnum直接进入left堆,再将left堆定元素放入堆right
    • num > x num直接进入right

C++代码

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);
                left.push(right.top());
                right.pop();
            }
        }
        else
        {
            if(num <= left.top())
            {
                left.push(num);
                right.push(left.top());
                left.pop();
            }
            else 
                right.push(num);
        }
    }
    
    double findMedian() 
    {
        if(left.size() == right.size()) 
            return (left.top() + right.top()) / 2.0;

        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.coloradmin.cn/o/2191476.html

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

相关文章

Python 语言学习——应用1.2 数字图像处理(第二节,变换)

目录 1.基础知识 1.图像几何变换概念 2.图像几何变换方式 3.插值运算 4.几何变换步骤 2.各类变换 1.位置变换 2.形状变换 3.代数运算 3.实战演练 1.基础知识 1.图像几何变换概念 在图像处理过程中&#xff0c;为了观测需要&#xff0c;常常需要对 图像进行几何变换&am…

EXCEL_光标百分比

Public Sub InitCells()Dim iSheet As LongFor iSheet Sheets.Count To 1 Step -1Sheets(iSheet).ActivateActiveWindow.Zoom 85ActiveWindow.ScrollRow 1ActiveWindow.ScrollColumn 1Sheets(iSheet).Range("A1").ActivateNext iSheetEnd Sub对日项目中的文档满天…

Python | Leetcode Python题解之第459题重复的子字符串

题目&#xff1a; 题解&#xff1a; class Solution:def repeatedSubstringPattern(self, s: str) -> bool:def kmp(query: str, pattern: str) -> bool:n, m len(query), len(pattern)fail [-1] * mfor i in range(1, m):j fail[i - 1]while j ! -1 and pattern[j …

深度学习中的结构化概率模型 - 结构化概率模型的深度学习方法篇

序言 在深度学习的广阔领域中&#xff0c;结构化概率模型&#xff08; Structured Probabilistic Model \text{Structured Probabilistic Model} Structured Probabilistic Model&#xff09;扮演着至关重要的角色。这类模型利用图论中的图结构来表示概率分布中随机变量之间的…

普渡PUDU MT1:AI赋能,破解大面积场景清洁新挑战

普渡AI智能扫地机器人PUDU MT1:破解大面积场景清洁难题的新利器 在仓储物流、工业车间、交通枢纽、大型商场等大面积场景中,清洁难题一直是管理者们头疼的问题。这些区域面积广阔,清洁任务繁重,传统清洁方式难以胜任。然而,普渡机器人最新推出的AI智能扫地机器人PUDU MT1…

【目标检测】工程机械车辆数据集2690张4类VOC+YOLO格式

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2694 标注数量(xml文件个数)&#xff1a;2694 标注数量(txt文件个数)&#xff1a;2694 标注…

付费计量系统数据元素(Data elements)

See also Clause 4 for a discussion on general concepts.Data elements are the instruments used to keep record of information on the status of the system and changes over time. 参见条目 4 关于一般概念的讨论。数据元素是仪器使用保留关于系统状态和随时间…

【Kubernetes】常见面试题汇总(四十五)

目录 102.使用 Kubernetes 时可以采取的最佳安全措施是什么&#xff1f; 103.什么是联合集群&#xff1f; 特别说明&#xff1a; 题目 1-68 属于【Kubernetes】的常规概念题&#xff0c;即 “ 汇总&#xff08;一&#xff09;~&#xff08;二十二&#xff09;” 。 题目…

1688商品详情关键词数据-API

要利用 Python 爬虫采集 1688 商品详情数据&#xff0c;需要先了解 1688 网站的页面结构和数据请求方式。一般使用 requests 库请求网站的数据&#xff0c;使用 BeautifulSoup 库解析网页中的数据。 以下是一个简单的 Python 爬虫采集 1688 商品详情数据的示例代码&#xff1a…

二、变量与基本类型

变量与基本类型 变量定义声明和使用 基本类型数字类型介绍运算算术运算符位运算符赋值运算符运算符优先级 布尔类型字符类型字符串类型 变量 定义 变量&#xff0c;指值可以变的量。变量以非数字的符号来表达&#xff0c;一般用拉丁字母。变量的用处在于能一般化描述指令的方式…

Java_Se 泛型

泛型基本概念&#xff1a; 泛型是JDK5.0以后增加的新特性。泛型的本质就是“数据类型的参数化”&#xff0c;处理的数据类型不是固定的&#xff0c;而是可以作为参数传入。我们可以把“泛型”理解为数据类型的一个占位符(类似&#xff1a;形式参数)&#xff0c;即告诉编译器&am…

如何搭建自己的域名邮箱服务器?Poste.io邮箱服务器搭建教程,Linux+Docker搭建邮件服务器的教程

Linux系统Docker搭建Poste.io电子邮件服务器&#xff0c;搭建属于自己的域名邮箱服务器&#xff0c;可以无限收发电子邮件&#xff08;Email&#xff09;&#xff01; 视频教程&#xff1a;https://www.bilibili.com/video/BV11p1mYaEpM/ 前言 什么是域名邮箱&#xff1f; …

【深度学习】— softmax回归、网络架构、softmax 运算、小批量样本的向量化、交叉熵

【深度学习】— softmax回归、网络架构、softmax 运算、小批量样本的向量化、交叉熵 3.4 Softmax 回归3.4.1 分类问题3.4.2 网络架构 3.4.3 全连接层的参数开销3.4.4 softmax 运算3.4.5 小批量样本的向量化3.4.6 损失函数对数似然softmax 的导数 3.4.7 信息论基础熵信息量重新审…

MySQL 和 Elasticsearch 的应用场景

MySQL 和 Elasticsearch 的应用场景 一、MySQL 关系型数据库管理系统&#xff0c;用于存储和管理结构化数据。 存储数据场景&#xff1a; 企业的财务系统、人力资源系统等&#xff0c;需要存储和管理具有明确关系的数据&#xff0c;如员工信息表、工资表等&#xff0c;这些表…

一阶差分模板的频率响应

一阶差分模板不同于二阶差分模板&#xff0c;它是一个奇对称的模板&#xff0c;傅里叶变换是纯虚数&#xff0c;无法用图形直接显示傅里叶变换&#xff0c;只能显示幅值谱。 冈萨雷斯的这个图我一直很好奇是怎么显示的&#xff0c;也没有坐标轴标出变量表示。 如今终于想明白…

基于Es的分词查询通过高亮效果实现前端高亮显示!!!!

引言&#xff1a; 经常我们在浏览器界面搜索关键词的时候&#xff0c;浏览器返回给我们的页面都是高亮显示关键词的效果&#xff0c; 如下&#xff1a; 我们要简单实现这个效果很简单&#xff0c;可以通过多种办法&#xff0c;这里通过Es 的高亮效果实现给我们关键字字段加自…

FRP搭建内网穿透:云服务端 + 家用Linux/Windows主机【2024】

介绍 FRP是一个可以自己搭建内网穿透服务的开源项目&#xff0c;开源地址直达&#xff1a; FRP-GitHub 实际上frp由两个程序组成 ①frps:在服务端运行的程序 ②frpc:在客户端运行的程序 运作方式示意图如下 服务端 因为服务上使用了1Panel面板&#xff0c;直接在应用商店安…

每日一题|134. 加油站|循环数组单次遍历

本题题目比较绕&#xff0c;理解了之后发现就是给一个一维数组表示余量&#xff0c;找出能够首尾相连且后构成每个位置处的累积和都是正数的索引。 首先&#xff0c;根据cost和gas相减&#xff0c;确定每个位置出发去下一个位置所剩余的gas。 这里可以直接统计全部的余量和&…

【德国EnMAP高光谱卫星】

德国EnMAP&#xff08;Environmental Mapping and Analysis Program&#xff09;高光谱卫星是德国在地球观测领域的一项重要成就&#xff0c;以下是对该卫星的详细介绍&#xff1a; 一、基本信息 发射时间&#xff1a;2022年4月1日研发机构&#xff1a;由德国航空航天中心&a…

【多模态项目实战】-模态表示:基于对应表示的跨模态检索(图文互搜)

【多模态项目实战】-模态表示&#xff1a;基于对应表示的跨模态检索 文章目录 【多模态项目实战】-模态表示&#xff1a;基于对应表示的跨模态检索1.任务介绍2.跨模态检索技术简介3.模型训练流程3.1读取数据1)下载数据集&#x1f680;2)整理数据集3)定义数据集类4)批量读取数据…