代码随想录算法训练营第十一天| 150. 逆波兰表达式求值 239. 滑动窗口最大值 347.前 K 个高频元素

news2024/11/13 9:27:48

目录

  • 一、LeetCode 150. 逆波兰表达式求值
    • 思路:
    • C++代码
  • 二、LeetCode 239. 滑动窗口最大值
    • 思路
    • C++代码
  • 三、LeetCode 347.前 K 个高频元素
    • 思路
    • C++代码
  • 总结


一、LeetCode 150. 逆波兰表达式求值

题目链接:LeetCode 150. 逆波兰表达式求值

文章讲解:代码随想录
视频讲解:栈的最后表演! | LeetCode:150. 逆波兰表达式求值

思路:

 本题要求逆波兰表达式(后缀表达式)的值,后缀表达式实际上是一棵运算二叉树的后序遍历序列,中间结点为运算符,左右孩子为运算数字。由于后序遍历可以借助递归来实现,那么同样的,我们借助栈也能实现对这棵表达式二叉树的遍历运算。

 具体算法思路为:当遍历到数字时,数字入栈;遍历到运算符时,将栈中最上面两个元素出栈,分别作为目标操作数( D S T DST DST)和源操作数( S R C SRC SRC),使用运算符运算后,将结果存在SRC中,运算结果入栈。表达式遍历结束后,栈中剩余的元素就是运算结果。
在这里插入图片描述

C++代码

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        long long src, dst;
        stack<long long> nums;
        for (int i = 0; i < tokens.size(); i++) {
            if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" ||
                tokens[i] == "/") {
                dst = nums.top();
                nums.pop();
                src = nums.top();
                nums.pop();
                if (tokens[i][0] == '+') {
                    src += dst;
                } else if (tokens[i][0] == '-') {
                    src -= dst;
                } else if (tokens[i][0] == '*') {
                    src *= dst;
                } else if (tokens[i][0] == '/') {
                    src /= dst;
                }
            } else {
                src = stoll(tokens[i]);
            }
            nums.push(src);
        }
        int result = nums.top();
        nums.pop();
        return result;
    }
};

二、LeetCode 239. 滑动窗口最大值

题目链接:添加链接描述

文章讲解:代码随想录
视频讲解:单调队列正式登场!| LeetCode:239. 滑动窗口最大值

思路

 本题可以自行构建一个单调队列进行解决。

 单调队列,即队列中的元素按照一定顺序排列的数据结构。由于我们本题需要找出滑动窗口最大元素,因此我们可以自己构建一个降序的单调队列,队头为最大元素。单调队列设置一个自我维护的机制,即元素大于前面元素的时候,弹出前面元素,新元素入队尾,可以保证队列中的元素一定是降序排列的。
在这里插入图片描述

C++代码

class Solution {
private:
    class MonoQue{  //构建单调队列,队列头部即为滑动窗口最大值
    public:
        deque<int> queue;

        void push(int value){
            while(!queue.empty() && value > queue.back()){ 
            //大于号确保了不存在重复元素
                queue.pop_back();  //从尾部入队,如果前面的元素小则弹出
            }
            queue.push_back(value);
        }

        void pop(int value){
            if(value == queue.front()){ //队列中没有重复元素,可以直接判断相等
                queue.pop_front();
            }
        }
    };
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> output;
        MonoQue que;
        for(int i = 0; i < k; i++){ //第一个窗口中的元素入队
            que.push(nums[i]);
        }
        output.push_back(que.queue.front());
        for(int i = k; i < nums.size(); i++){
            que.pop(nums[i-k]);
            que.push(nums[i]);
            output.push_back(que.queue.front());
        }
        return output;
    }
};

三、LeetCode 347.前 K 个高频元素

题目链接:LeetCode 347.前 K 个高频元素

文章讲解:代码随想录
视频讲解:优先级队列正式登场!大顶堆、小顶堆该怎么用?| LeetCode:347.前 K 个高频元素

思路

 需要返回出现频率最高的前几个元素,首先我们需要统计各个元素出现次数,这里使用一种哈希结构unordered_map来实现统计;

 统计结束后,需要对元素按照出现频率进行排序。我们选择构建一个优先级队列(小顶堆)

priority_queue<pair<int,int>, vector<pair<int,int>>, comparison> pri_que;

 其中尖括号内第一项是数据类型,第二项是实现该结构的底层容器,第三项是维护优先级队列的比较函数。

 构建优先队列实现小顶堆,使堆中元素保持在3个,这样可以保证每次弹出的都是频率最小的元素,最后留在堆中的就是出现频率最大的元素。

C++代码

class Solution {
public:
    class comparison{
    public:
        bool operator()(const pair<int,int> &l, const pair<int,int> &r){ //定义小顶堆比较函数
            return l.second > r.second;
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int> freq_map;
        for(int x: nums){ //map统计出现频率
            freq_map[x]++;
        }

        priority_queue<pair<int,int>, vector<pair<int,int>>, comparison> pri_que;
        //分别定义优先队列数据类型、底层容器与比较函数
        for(auto it = freq_map.begin(); it != freq_map.end(); it++){
            pri_que.push(*it);
            if(pri_que.size() > k){ //保证固定大小k
                pri_que.pop(); //小顶堆优先弹出最小值,因此后续可直接输出堆中k个值
            }
        }
        vector<int> result;
        while(!pri_que.empty()){
            result.push_back(pri_que.top().first);
            pri_que.pop();
        }
        return result;

    }
};

总结

 接触到了单调队列和优先级队列两个新工具,对于滑动窗口最大值和前k个高频元素的代码思想应再进行复习理解。


文章图片来源:代码随想录 (https://programmercarl.com/)

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

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

相关文章

D - Pedometer AtCoder Beginner Contest 367

题意: 一个长度为n的数组a首尾相接&#xff0c;求满足a[i]~a[j]的和是m的倍数的[i,j]对数 思路&#xff1a; 由于首位相接&#xff0c;那么区间i-->j的所有数有两种情况&#xff1a;第一种是i<j的情况&#xff0c;第二种是i>j的情况 为了简化处理&#xff0c;我们可…

信息学奥赛初赛天天练-74-NOIP2016普及组-基础题5-树、父节点、根节点、叶子节点、非叶节点、组合、组合排除法

NOIP 2016 普及组 基础题5 21 从一个 44的棋盘&#xff08;不可旋转&#xff09;中选取不在同一行也不在同一列上的两个方格&#xff0c;共有( )种方法。 22 约定二叉树的根节点高度为 1。一棵结点数为 2016 的二叉树最少有( )个叶子结点&#xff1b;一棵结点数为 2016 的二叉…

STM32 HAL SDADC DMA

1、简介 由于项目需要使用STM32F373单片机的SDADC功能对电位计进行检测,网上资料比较少,踩了很多坑,下面进行总结。 2、STM32CubeMX配置 2.1 RCC配置 2.2 SYS 配置 2.3 SDADC 2 配置 2.3.1 Parameter Settings配置 SDADC共有三种输入模式,分别为差分模式、 单端偏移模…

Web-ssrfme

文章目录 环境分析攻击 环境 首先下载资源包&#xff0c;Ubuntu通过docker拉取环境。 docker-compose up -d分析 <?php highlight_file(__file__); function curl($url){ $ch curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_HEADER, 0);e…

开源在线文档管理工具MrDoc

MrDoc&#xff0c;也被称为觅思文档或觅道文档&#xff0c;是一款基于Python开发的在线文档系统。它支持Markdown和所见即所得的富文本编辑&#xff0c;适合个人和小型团队作为文档、笔记和知识管理工具。 开源地址&#xff1a;MrDoc: MrDoc觅思文档&#xff0c;适合于个人和中…

Vue | 简单说说 Vuex 实现响应式的原理

Vuex 通过结合 Vue.js 的响应式系统实现了状态的响应式。Vuex 的状态存储于 Vue 的 data 对象中&#xff0c;这确保了对状态的任何 mutation 都是响应式的。 Vuex 使用单一状态树&#xff0c;并通过响应式来进行状态管理。其响应式的实现主要依赖于 Vue 的响应式系统。 Vuex 的…

Linux简单介绍(1)

一、Linux简介与安装 1.1 计算机的相关概念 1. 什么是计算机? 能够接收使用者输入的指令与数据&#xff0c;经由中央处理器的算术与逻辑单元运算处理后&#xff0c;以产生或存储有用的新数据。比如计算器&#xff0c;手机&#xff0c;汽车导航系统&#xff0c;提款机&am…

借题《黑神话悟空》,聊聊UE5 游戏开发中基本的 C++ 概念

最近火的一塌糊涂的《黑神话悟空》就是用UE5引擎开发的。借题发挥&#xff0c;今天讲讲UE游戏开中的一些C基本概念&#xff1b; 编写代码与蓝图&#xff08;可视化脚本&#xff09;相结合具有独特的功能&#xff0c;您需要利用这些功能来实现两全其美。编程可以帮助创建更复杂…

DevEcoStudio启动模拟器提示未开启Hyper-V

处理方式&#xff1a;&#xff08;win11专业版系统&#xff09; 勾选Hyper-V。 如果提示无法安装Hyper-v&#xff1a;该固件中的虚拟化支持被禁用。如下图&#xff1a; 需要进入BIOS启用虚拟化技术。 这个根据电脑主板不一样&#xff0c;操作方法不同&#xff0c;请自行搜索处…

LCD模组驱动开发

Linux 5.15 内核适配 驱动勾选 由于使用的是 SPI0&#xff0c;所以 TinyVision 的 LCD 模块并不支持使用MIPI-DBI进行驱动&#xff0c;这里我们使用普通的SPI模拟时序。 勾选 SPI 驱动 这里我们使用 SPI-NG 驱动&#xff0c;勾选 <*> SPI NG Driver Support for Allw…

Apifox测试SOAP接口教程

文章目录 I 请求webservice接口使用Apifox测试工具来测试soap接口配合Charles测试soap接口(前提:允许使用系统代理)使用hutool的SoapClient调用soap接口II 扩展知识webService三要素SOAP消息组成(SOAP请求消息的格式)浏览器访问暴露出的soap接口需求: AIS数据对接给其他平…

画板555

p41 这两个地 都是 板框这里按 Q可以改单位放置在原点p42 布局 和原理图一样都是 模块化 布局 (一样的放一起)原理图中选中 PCB里也会选中位号 布局时 一般放在中间因为在别的地可能会影响布局全选后 布局里的属性位置不用全选也行点击查找全部 就选上了 能看到就行板框确定好…

leetcode47. 全排列 II有重复元素的全排列,深度优先搜索

leetcode47. 全排列 II/有重复元素的全排列 给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2] 输出&#xff1a; [[1,1,2], [1,2,1], [2,1,1]] 示例 2&#xff1a; 输入&#xff1a;…

【数据结构4】树的实例-模拟文件系统、二叉树的遍历(先序遍历、中序遍历、后序遍历、层次遍历)

1 树和二叉树 2 树的实例-模拟文件系统 3 二叉树 3.1 二叉树的遍历 二叉树的先序遍历 二叉树的中序遍历 二叉树的后序遍历 二叉树的层次遍历 1 树 树是一种数据结构 比如:目录结构 树是一种可以递归定义的数据结构树是由n个节点组成的集合:如果n0&#xff0c;那这是一棵空树;如…

测试用例(还需要输入1个字)

近期机缘巧合&#xff0c;连续写2个项目的测试用例。第一个项目&#xff0c;纯属没有办法&#xff0c;参与该项目的现在就只剩我一个人了&#xff0c;只能自己写了&#xff0c;这不&#xff0c;我专门跑到客户那啥都不干&#xff0c;写文档写了2天&#xff1b;第二个项目&#…

如何使用gewe开发微信机器人

本文介绍了如何利用GeWe框架开发一个功能丰富的微信智能机器人。GeWe是一个开发协议&#xff0c;为微信机器人提供了强大的功能支持&#xff0c;包括关键字回复、自动通过好友和自动发朋友圈等特性。我们将通过一个简单的示例演示如何在GeWe框架下实现这些功能&#xff0c;并附…

模型 空雨伞

列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。观察现状&#xff0c;分析原因&#xff0c;制定行动。 1 空雨伞模型的应用 1.1 空雨伞模型应用之API对接的决策 某公司产品经理A君接到了与合作方对接API的任务。合作方对公司的中台API有特定的需求&…

有什么办法能恢复郎科u盘的数据?常用方法分享

在数字化时代&#xff0c;数据已成为我们生活与工作中不可或缺的一部分。郎科U盘&#xff0c;以其便携、稳定的特性&#xff0c;成为了许多人存储重要文件的首选。然而&#xff0c;面对突如其来的数据丢失&#xff0c;无论是误删、格式化还是病毒侵袭等&#xff0c;都足以让人心…

【Qt】常见控件 —— QWidget(上)

文章目录 QWidget 的基本介绍QWidget 的 enable 属性QWidget 的 geometry属性QWidget 的 windowTitle属性 QWidget 的基本介绍 Qt 中 的 各种控件 都继承自 QWidget类 在 Qt designer 右侧 就显示出 QWidget的各种属性 并且也可以直接进行编辑 QWidget 的 enable 属性 enable…

ETAS工具链自动化实战指南<二>

----自动化不仅是一种技术&#xff0c;更是一种思维方式&#xff0c;它将帮助我们在快节奏的工作环境中保持领先&#xff01; 目录 往期推荐 RTA-A2L工具概览 RTA-A2L的输出文件 常用命令行参数 场景1&#xff1a;通过 MCSD 文件来生成 .a2l 文件并更新地址 命令用法 命…