算法_优先级队列---持续更新

news2024/9/23 17:22:31

文章目录

  • 前言
  • 最后一块石头重量
    • 题目要求
    • 题目解析
    • 代码如下
  • 数据流中的第K大元素
    • 题目要求
    • 题目解析
    • 代码如下
  • 前K个高频单词
    • 题目要求
    • 题目解析
    • 代码如下
  • 数据流的中位数
    • 题目要求
    • 题目解析
    • 代码如下

前言

本文将会向你分享优先级队列相关的题目:最后一块石头重量、数据流中的第K大元素、前K个高频单词、数据流的中位数

最后一块石头重量

https://leetcode.cn/problems/last-stone-weight/

题目要求

在这里插入图片描述

题目解析

题目要求每次从一堆数中找出最大的两个,然后再进一步判断,最重要的是如何从一堆数中找出最大的数,这时可以想到用大根堆,最大的在堆顶,pop堆顶,就可以拿到次大的了。

代码如下

class Solution {
public:
    int lastStoneWeight(vector<int>& stones) 
    {
        priority_queue<int> heap;   //优先级队列,默认是一个大根堆
        for(auto& e : stones)
        {
            heap.push(e);
        }
        while(heap.size() > 1)
        {
            int x = heap.top(); heap.pop();
            int y = heap.top(); heap.pop();
            if(x > y) heap.push(x - y);
        }
        return heap.size() ? heap.top() : 0;
    }
};

数据流中的第K大元素

https://leetcode.cn/problems/jBjn9C/

题目要求

在这里插入图片描述

题目解析

题目要求是找到数据流中的第K大元素,那么把这些数据放到一个小根堆中就可以解决,题目有点绕(将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素),其实就是外部调用add函数传入的val 有数据流1,2,3,4。比如需要求第3(K)大的元素,我们知道是2,只需要将小根堆的元素个数维持为3(K)个,那么堆顶元素就是我们需要求的第3大的元素。 也就是当堆里的元素大于K,就pop,这样就能维持堆里的元素等于K

在这里插入图片描述
在这里插入图片描述

代码如下

class KthLargest {
public:
    priority_queue<int, vector<int>, greater<int>> heap;
    int k = 0;
    KthLargest(int k, vector<int>& nums) 
    {
        this->k = k;
        for(auto& e : nums)
        {
            add(e);
        }
    }
    //确保堆始终包含k个最大的元素,堆顶将是第k大的元素
    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个高频单词

https://leetcode.cn/problems/top-k-frequent-words/

题目要求

在这里插入图片描述

题目解析

题目要求返回前k个出现次数最多的单词,那么很容易想到的是建一个小堆,维持小堆的个数未为k个,堆里剩下的就是次数出现最多的,但是题目中有额外要求,如果单词出现的频次相同,那么就按字典顺序排序。那么我们是需要自定义比较函数的

当second(频次)相同,那么按照字典序排序,也就是小的排在前面,a.first < b.first也就是小的排在前面, a.second > b.second频次大的排在后面

在这里插入图片描述

if(a.second == b.second)
{   
    return a.first < b.first;   //按照字典顺序排序
}
else return a.second > b.second;   

代码如下

class Solution {
public:
    struct cmp
    {
        bool operator()(const pair<string, int>& a, const pair<string, int>& b)
        {
            //单词出现的频率相同
            if(a.second == b.second)
            {   
                return a.first < b.first;   //按照字典顺序排序
            }
            else return a.second > b.second;    //小根堆,大的排在下面
        }
    };
    vector<string> topKFrequent(vector<string>& words, int k) 
    {
        unordered_map<string, int> hash;    //用哈希表统计单词次数
        for(auto& e : words)
        {
            hash[e]++;
        }
        //TopK,取前k个出现次数最多的单词
        priority_queue<pair<string, int>, vector<pair<string, int>>, 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;
    }
};

数据流的中位数

https://leetcode.cn/problems/find-median-from-data-stream/

题目要求

在这里插入图片描述

题目解析

题目要求实现中位数查找器,直接利用数组的个数/2来求中位数的方式是不够高效的,因为数据流是动态变化的。

这里可以用一个大小堆,小堆中的元素每个都比大堆中的元素大,每当数据来的时候,判断与大小堆顶的关系,插入到对应的堆中,需要注意的是还要维持大小堆中的元素个数,只有maxHeap,size() = minHeap.size() 或者 maxHeap,size() = minHeap.size()+1只有这两种情况才行。因为只有这样,如果数据流的元素个数为奇数,那么就是大堆堆顶,如果是偶数,就手动求一下(大堆堆顶+小堆堆顶)/2即可

ps:这种方法并不好想,这次记住就行啦!

在这里插入图片描述

代码如下

class MedianFinder {
public:
    MedianFinder() 
    {}
    
    void addNum(int num) 
    {
        int sz1 = maxHeap.size(), sz2 = minHeap.size();
        if(sz1 == sz2)
        {
            if(sz1 == 0 || num <= maxHeap.top())   //注意sz1 == 0要放到最前面,否则当堆中元素为空时,会空指针
                maxHeap.push(num); //直接插入
            else
            {
                minHeap.push(num); //此时sz2 == sz1 + 1
                int tmp = minHeap.top(); minHeap.pop();
                maxHeap.push(tmp);
            }
        }
        else    //sz1 == sz2+1
        {
            if(num <= maxHeap.top())
            {
                maxHeap.push(num);
                int tmp = maxHeap.top(); maxHeap.pop();
                minHeap.push(tmp);  //维持sz1 == sz2+1
            }
            else
            {
                minHeap.push(num);  //直接插入
            }
        }
    }
    
    double findMedian() 
    {
        if((maxHeap.size() + minHeap.size()) % 2 == 0)        
            return static_cast<double>(maxHeap.top() + minHeap.top()) / 2;
        else 
            return static_cast<double>(maxHeap.top());
    }
public:
    priority_queue<int, vector<int>, greater<int>> minHeap;
    priority_queue<int> maxHeap;
};

/**
 * 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/2126817.html

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

相关文章

【运维自动化-作业平台】脚本版本管理如何使用

在蓝鲸作业平台中&#xff0c;执行脚本是最常见的功能之一&#xff0c;支持快速录入脚本执行和引用脚本执行&#xff0c;引用的脚步即单独写好的&#xff0c;并且由定期管理更新的脚本&#xff0c;主要有业务脚本和公共脚本两种。快速脚本 手动页面编写的脚本&#xff0c;没有…

将小写字母转换为大写字母(c 语言)

2.我们第一步输入字符串&#xff0c;第二步进行筛选将字符串中所以下标为奇数位置上的字母转换成大写&#xff0c;如果该位置不是字母&#xff0c;则不转换。 #include <stdio.h> #include <string.h> void fun( char *ss ) {int i 0;while (*ss ! \0){if (i % 2…

ACL 2024:交叉领域情感分析——论文阅读笔记

前言 阅读了一篇ABSA的论文&#xff0c;在这里写下自己的一些理解小笔记&#xff0c;可能有点小乱&#xff0c;原文在这下面&#xff1a; 论文链接&#xff1a;Refining and Synthesis: A Simple yet Effective Data Augmentation Framework for Cross-Domain Aspect-based Sen…

swoole协程 是单线程的,还是多线程的

Swoole 协程本质上是单线程的&#xff0c;但它可以在多个线程中运行。因此&#xff0c;Swoole 协程既可以看作是单线程的&#xff0c;也可以在多线程的环境下运行&#xff0c;这取决于你如何使用 Swoole。 理解 Swoole 协程的运行模式 1 单线程中的协程&#xff1a; 在一个单…

构建常态化安全防线:XDR的态势感知与自动化响应机制

当前&#xff0c;网络安全威胁日益复杂多变&#xff0c;企业正面临前所未有的严峻挑战。为有效应对这些挑战&#xff0c;态势感知与自动化响应机制在提升网络安全运营效率与防御效果中扮演着至关重要的角色。它们能够实时监测网络状态&#xff0c;智能分析潜在威胁&#xff0c;…

浏览器中的JavaScript核心BOM(浏览器对象模型)重点掌握对象之History对象的属性与方法

History对象是用来把网页浏览历史用类似栈的方式进行表示。 这定义听起来非常的抽象&#xff0c;其实History对象的作用就跟浏览器的前进和后退很像&#xff0c;我们来用几幅图来理解一下。首先我们先回顾一下浏览器的返回上一个页面 和 跳转到下一个页面 这两个功能。 就类似…

【计算机网络】网络通信中的端口号

文章目录 一、引入端口号二、端口号的作用三、端口号的确定 在TCP/IP协议中&#xff0c;传输层有两个重要的协议&#xff1a;TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;。TCP用于提供可靠的数据传输&#xff0c;而UDP则适合用于广播…

labview对位项目

带角度对位 1、上下拍照对照 项目类型&#xff1a;模组、PACK入箱&#xff0c;以下以模组入箱为例 项目目标&#xff1a;机器人抓起模组&#xff0c;通过上相机定位箱体上的销钉&#xff0c;通过下相机定位模组上的端板孔&#xff0c;计算出旋转偏移量XYR&#xff0c;让模组上…

苹果能引领端侧AI大模型时代吗?

苹果能引领端侧AI时代吗&#xff1f; 这份完整版的大模型 AI 学习资料已经上传CSDN&#xff0c;朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】 北京时间9月10日凌晨&#xff0c;苹果正式发布了iPhone 16&#xff0c;这是苹果第一款真正意义上的 …

精品PPT | 离散制造行业智能工厂总体解决方案

一、建设背景 离散制造业&#xff0c;包括机械制造业、汽车制造业和家电制造业等&#xff0c;其生产过程涉及多个不连续的工序&#xff0c;产品通常由多个零件装配而成。这类行业面临的挑战包括品种多、批量小、订单变化快、临时插单频繁以及外协件管理困难等问题&#xff0c;…

相机光学(三十七)——自动对焦原理

1.自动对焦的三种方式 目前在手机上采用的自动对焦系统包括反差对焦、相位对焦和激光对焦三种方案&#xff0c;下面我们来看一下它们的工作原理和相互之间的区别是什么。 1.1反差对焦【CDAF】- Contrast Detection Auto Focus 反差对焦是目前普及率最高、使用最广泛、成本相对…

Leetcode 701-二叉搜索树中的插入操作

给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c;可能存在多种有效的插入方式&a…

QT之QML学习五:添加自定义Qml组件

开发环境: 1、Qt 6.7.2 2、Pyside6 3、Python 3.11.4 4、Windows 10 重要的事情说三遍,使用自定义qml参考链接: Qt官网参考网址!!! 重要的事情说三遍,使用自定义qml参考链接: Qt官网参考网址!!! 重要的事情说三遍,使用自定义qml参考链接: Qt官网参考网址!!!…

2024年华为杯数学建模研赛 最全赛中助攻|选题建议+思路+代码+成品论文预定

2024年华为杯研究生数学建模竞赛&#xff08;以下简研赛&#xff09;将于9月21日上午8时正式开始。 下文包含&#xff1a;2024研赛思路解析​、研赛参赛时间及规则信息说明、好用的数模技巧及如何备战数学建模竞赛 C君将会第一时间发布选题建议、所有题目的思路解析、相关代码…

【2024】Benchmarking Foundation Models with Language-Model-as-an-Examiner

信息 阅读目的&#xff1a;李娟子老师团队&#xff0c;了解模型中的知识评测的工作 白雨时1*、嘉豪英2*、曹义心2、吕新1、何玉泽1, 王笑之1 、于吉凡1 、曾凯生1 、小易佳3 , Haozhe Lyu 4张嘉荫1李娟子1 , Lei Hou 1 凶 1清华大学&#xff0c;北京&#xff0c;中国2新…

AI菜鸟向前飞 — LangGraph系列之一:深入浅出解读Graph(一)

前言 LangGraph是一个使用 LLM 和 LangChain 构建有状态多参与者应用程序的库。 LangChain 允许您使用 LCEL&#xff08;LangChain 表达式语言&#xff09;构建链 AI菜鸟向前飞 — LangChain系列之六 - 深入浅出LCEL与Chain(上篇) AI菜鸟向前飞 — LangChain系列之七 - 深入…

ALIENTEK电容按键按键的介绍与驱动代码

目录 前言 电容触摸按键原理 硬件接线 检测电容触摸按键过程 驱动代码 tpad.h tpad.c main.c 按键扫描函数 前言 我没有独立的电容触摸按键模块&#xff0c;所以使用正点原子STM32F103ZET6精英版开发板上的电容触摸按键。采用STM32F103C8T6检测电容触摸按键&#…

WEB渗透权限维持篇-隐藏windows服务

往期文章WEB渗透权限维持篇-DLL注入\劫持-CSDN博客 WEB渗透权限维持篇-CLR-Injection-CSDN博客 WEB渗透权限维持篇-计划任务-CSDN博客 WEB渗透权限维持篇-DLL注入-修改内存中的PE头-CSDN博客 WEB渗透权限维持篇-DLL注入-进程挖空(MitreT1055.012)-CSDN博客 WEB渗透权限维持…

mysql设置数据库隔离级别及各个隔离级别的作用

一、通过命令设置隔离级别 # 设置全局隔离级别 set global transaction isolation level REPEATABLE READ; set global transaction isolation level READ COMMITTED; set global transaction isolation level READ UNCOMMITTED; set global transaction isolation level SE…

Reduce:一款开源的短网址平台!!【送源码】

今天给大家介绍一款开源的短网址平台&#xff0c;Coody Framework首秀&#xff0c;自写IOC、MVC、ORM、TASK、JSON、DB连接池、服务器。百毫秒启动&#xff0c;全项目仅2.5M&#xff08;低配服可运行&#xff09;。 前端采用Amaze UI&#xff0c;后端采用Coody Framework MVC&…