力扣刷题总结 栈与队列

🔥博客主页: A_SHOWY
🎥系列专栏:力扣刷题总结录 数据结构  云计算  数字图像处理  力扣每日一题_

一、栈和队列的基础知识

队列是先进先出,栈是先进后出。同时二者都是容器适配器而不是容器。

 二、题目实战

232.用栈实现队列easy基础操作
225.用队列实现栈easy基础操作
20.有效的括号easy碰到左括号存栈里,等右括号匹配
1047.删除字符串中所有的重复项mid匹配相邻元素消除
150.逆波兰式求和mid字符转换整型
239.滑动窗口的最大值hard双值队列的应用,巧妙

(1)232.用栈实现队列

232. 用栈实现队列icon-default.png?t=N7T8https://leetcode.cn/problems/implement-queue-using-stacks/我们知道栈是先进先出,队列是先进后出。所以要用栈来实现队列,需要一个输入栈一个输出栈(按输入的顺序倒叙存放)。这个题目有四个操作

1.第一个操作很容易就是一个入队列的操作和入栈一样 

​void push(int x) {stkIn.push(x);}

2.第二个操作是出队列的操作,这个操作就有一定的难度,我们需要一个 输入栈和一个输出栈,当输出栈为空的时候,我们需要把输入栈的所有元素全部弹出到输出栈,这样从输出栈进行pop这个顺序满足先入先出。输出栈弹出的第一个元素就我们的结果。

  int pop() {//当out栈为空的时候if(stkOut.empty()){while(!stkIn.empty()){//把所有in栈里面的东西全部弹出给out,否则顺序不对stkOut.push(stkIn.top());stkIn.pop();}}int res = stkOut.top();stkOut.pop();return res;

3.第三个操作是返回队列开头的元素,我们发现和第二个操作是大量重复代码相似的操作,所以我们可以直接复制第二问的代码,但是我们专业来说可以用this->来直接调用同一个类中的函数,调用结束后发现多弹出一个元素,我们再push回去就可以了。

int peek() {//学会运用this->,这里发现和pop操作的代码大同小异int res = this -> pop();//发现这里多弹出了stkOut.push(res);return res;}

第四个操作是 判断队列是否为空,直接判断入栈和出栈相与为空,说明两个栈都没有元素时为空既可。

 bool empty() {return stkIn.empty() && stkOut.empty();}

 (2)225.用队列实现栈

225. 用队列实现栈icon-default.png?t=N7T8https://leetcode.cn/problems/implement-stack-using-queues/这道题目其实就是用一个队列来实现栈,具体思路和上一题有很多相似之处。

1.首先第一个问题还是一个push操作,栈和队列的push操作是一样的,所以可以直接push

void push(int x) {q.push(x);}

2.第二个pop操作还是整个题目最需要思考的。当一个队列的时候,我们的整体思路是把size-1个元素取出来然后重新push进入队列。再pop队列front的元素一次。

int pop() {int size = q.size();size--;while(size--){q.push(q.front());q.pop();}int res = q.front();q.pop();return res;}

3.第三个操作直接使用back就可以解决 

    int top() {return q.back();}

4.第四个操作,空值操作

bool empty() {return q.empty();}

可以看出来整体思路还是比较简单的,除了pop操作需要多思考一下,其他小问的要求容易。

拓展:如果要求使用两个队列来满足栈的pop操作

将第一个队列的size-1个元素移动到第二个队列中 ,留下的最后一个元素就是要返回的值,再把第二个队列中的元素移动到第一个队列中即可。核心思想不变。但是记住要把q1最后清空。

 int pop() {//  int size = q.size();//  size--;//  while(size--){//      q.push(q.front());//      q.pop();//  }//  int res = q.front();//  q.pop();//  return res;int size = q.size();size--;while(size--){q1.push(q.front());q.pop();}int res = q.front();q.pop();q = q1;//还要清空q1while(!q1.empty()){q1.pop();}return res;}

(3)20.有效的括号

20. 有效的括号icon-default.png?t=N7T8https://leetcode.cn/problems/valid-parentheses/栈非常适合做这种匹配的问题,有一个小技巧,就是碰到左括号,就存一个右括号到栈里,再进行匹配。

class Solution {
public:bool isValid(string s) {stack<char> st;for(int i = 0; i< s.size();i++){if(s[i] == '(') st.push(')');else if(s[i] == '{') st.push('}');else if(s[i] == '[') st.push(']');//第二种else if(st.empty() || s[i] != st.top()) return false; else st.pop();}return (st.empty());}
};

(4)1047.删除字符串中所有重复项

1047. 删除字符串中的所有相邻重复项icon-default.png?t=N7T8https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/ 本题要删除相邻相同元素,相对于20. 有效的括号 (opens new window)来说其实也是匹配问题,20. 有效的括号是匹配左右括号,本题是匹配相邻元素,最后都是做消除的操作。用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。这种消除问题也是栈的经典题目。

class Solution {
public:string removeDuplicates(string s) {stack<char> st;for(char x : s){if(st.empty() || x != st.top()) st.push(x);//如果为空或者不相等直接pushelse st.pop();//否则pop}
//输出操作,栈先进后出,所以最好输出要反过来string result = "";while(!st.empty()){result += st.top();st.pop();}reverse(result.begin(),result.end());return result;}
};

(5) 150.逆波兰表达式求和

150. 逆波兰表达式求值icon-default.png?t=N7T8https://leetcode.cn/problems/evaluate-reverse-polish-notation/

本题也是一道和栈有关的题目,要求求逆波兰式的求值,对于这道题目,我们可以考虑到当在一个栈中栈顶为符号的时候,就从栈顶拿出来两个元素进行符号操作再放回栈顶。

需要注意的是这道题给的范围定义的long long的栈,最后字符串转换的时候要用long long的stoll

注意本题给的是tokens数组中全部都是字符串,所以在push的时候需要进行转化 

stoi 函数:将字符串转成 int 整数。 stol 函数:将字符串转成 long 整数。 stoll 函数:将字符串转成 long long 整数。 

class Solution {
public:int evalRPN(vector<string>& tokens) {
stack<int> st;for(int i = 0 ; i < tokens.size(); i++){if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/")      {int nums1 = st.top();st.pop();int nums2 = st.top();st.pop();if(tokens[i] == "+") st.push(nums2 + nums1);if(tokens[i] == "-") st.push(nums2 - nums1);if(tokens[i] == "*") st.push(nums2 * nums1);if(tokens[i] == "/") st.push(nums2 / nums1);}else st.push(stoi(tokens[i]));}return st.top();}
};

(6)239.滑动窗口的最大值

239. 滑动窗口最大值icon-default.png?t=N7T8https://leetcode.cn/problems/sliding-window-maximum/这道题目是一个hard题目,思路确实很难,对于本题,我们需要一个队列,这个队列呢,放进去窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。

队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了,同时保证队列里的元素数值是由大到小的。那么这个维护元素单调递减的队列就叫做单调队列,即单调递减或单调递增的队列。

我们用到的自定义的队列是一个deque,双向队列,也就是左右都能进出。我们先考虑push函数,在我们每次push的时候,当要push的元素比前面的都大时,把前面的元素全部删除,因为我们不需要维护所有的元素,我们只需要保证最大元素即可,可能有人就迷惑了,你把前面的元素都卷走了,那pop操作怎么办。pop操作就更为巧妙了,当要pop的元素和队列的front相等的时候,才是真正要pop 的时候。但是对于push和pop函数队列操作不要忘记队列不为空的判断,front函数就简单了,直接返回队列的front就可以。

在实现函数部分,先把前k个元素push进队列,找到最大的值,然后从第k+1个元素进行push,pop,front操作。最后放到数组里面返回。

class Solution {
private:
class MyQueue{
public:deque<int> que;void pop(int value){if(!que.empty() && que.front() == value){que.pop_front();} }void push(int value){while(!que.empty() && value > que.back()){que.pop_back();}que.push_back(value);}int front(){return que.front();}
};
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {MyQueue que;vector<int> res;for(int i = 0 ; i < k; i++){que.push(nums[i]);//先把前k个push进去}res.push_back(que.front());//记录前k个元素的最大值for(int i = k; i < nums.size();i++){que.pop(nums[i-k]);que.push(nums[i]);res.push_back(que.front());}
return res;}
};

这道题目的重点是我们要确定维护的是大的元素,前面的元素较小在push操作时候就会被顶出。

本期总结了道题目,后续如果有相关题目会继续总结添加。 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity AssetBundle学习笔记

目录 基础介绍 动态资源加载 更新和添加内容 打包策略 资源分组 频繁更新的资源 资源压缩 Unload&#xff08;true&#xff09;和Unload&#xff08;false&#xff09; Unload(false) Unload(true) 确定何时卸载 引用计数 场景和状态管理 资源使用频率 内存预算…

基于CNN神经网络的手写字符识别实验报告

作业要求 具体实验内容根据实际情况自拟&#xff0c;可以是传统的BP神经网络&#xff0c;Hopfield神经网络&#xff0c;也可以是深度学习相关内容。 数据集自选&#xff0c;可以是自建数据集&#xff0c;或MNIST&#xff0c;CIFAR10等公开数据集。 实验报告内容包括但不限于&am…

前端图片适配不同屏幕方案

预备知识&#xff1a; 设备独立像素,以下图的iphone12 Pro为例&#xff0c;390*844表示的就是设备独立像素&#xff08;DIP&#xff09;,也可以理解为CSS像素 物理像素&#xff08;设备像素&#xff09;&#xff0c;就是屏幕的分辨率&#xff0c;显示屏就是由一个个物理像素…

【vim 学习系列文章 3.1 -- vim 删除 ^M】

请阅读【嵌入式开发学习必备专栏 之 VIM 专栏】 文章目录 ^M 来源^M 删除 ^M 来源 在 Vim 中打开文件时&#xff0c;您可能会遇到行尾的 ^M 字符&#xff0c;这通常是因为文件使用了 Windows 风格的回车换行符&#xff08;CRLF&#xff09;&#xff0c;而不是 Unix/Linux 风格…

Java - 工厂设计模式

Java - 工厂设计模式 一. 简介二. 例子2.1 定义抽象类2.2 定义子类2.3 创建工厂2.4 测试 三. JDK中使用工厂模式的案例 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 工厂设计模式…

基于JAVA+SSM+VUE的前后端分离的大学竞赛管理系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着互联网技术的快速…

尽量避免删改List

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

【代码随想录】刷题笔记Day42

前言 这两天机器狗终于搞定了&#xff0c;一个控制ROS大佬&#xff0c;一个计院编程大佬&#xff0c;竟然真把创新点这个弄出来了&#xff0c;牛牛牛牛&#xff08;菜鸡我只能负责在旁边喊加油&#xff09;。下午翘了自辩课来刷题&#xff0c;这次应该是元旦前最后一刷了&…

苹果CMS超级播放器专业版无授权全开源,附带安装教程

源码介绍 超级播放器专业版v1.0.8&#xff0c;内置六大主流播放器&#xff0c;支持各种格式的视频播放&#xff0c;支持主要功能在每一个播放器内核中都相同效果。 搭建教程 1.不兼容IE浏览器 2.php版本推荐7.4 支持7.1~7.4 3.框架引入不支持同时引入多个播放器 json对接教…

搭建maven私服

maven maven简介 什么是maven&#xff1f; Maven这个单词来自于意第绪语&#xff08;犹太语&#xff09;&#xff0c;意为知识的积累。 Maven项目对象模型(POM)&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的项目管理工具软件。 Maven 除了以…

数据结构与算法 - 查找

文章目录 第1关&#xff1a;实现折半查找第2关&#xff1a;实现散列查找 第1关&#xff1a;实现折半查找 代码如下&#xff1a; /*************************************************************date: April 2009copyright: Zhu EnDO NOT distribute this code. ***********…

记录一下imx6ull linux 5.10.9多点电容触摸屏驱动报错问题解决方法

最近再研究如何将linux 5.10.9移植到imx6ull&#xff0c;用的原子的开发板&#xff0c;在移植电容触摸屏驱动时报错gpio gpiochip0: (209c000.gpio): gpiochip_lock_as_irq: tried to flag a GPIO set as output for IRQ&#xff0c;如下图&#xff1a; 该错误的意思就是尝试将…

Flink1.17实战教程(第三篇:时间和窗口)

系列文章目录 Flink1.17实战教程&#xff08;第一篇&#xff1a;概念、部署、架构&#xff09; Flink1.17实战教程&#xff08;第二篇&#xff1a;DataStream API&#xff09; Flink1.17实战教程&#xff08;第三篇&#xff1a;时间和窗口&#xff09; Flink1.17实战教程&…

[足式机器人]Part2 Dr. CAN学习笔记-Ch00 - 数学知识基础

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-Ch00 - 数学知识基础 1. Ch0-1矩阵的导数运算1.1标量向量方程对向量求导&#xff0c;分母布局&#xff0c;分子布局1.1.1 标量方程对向量的导数1.1.2 向量方程对向量的导数 1.2 案例分析&#xf…

Java项目:101SpringBoot仓库管理系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 仓库管理系统基于SpringBootMybatis开发&#xff0c;系统使用shiro框架做权限安全控制&#xff0c;超级管理员登录系统后可根据自己的实际需求配角色&…

项目中使用Java中List.subList()的注意事项

使用介绍 在Java中&#xff0c;subList是List接口的一个方法&#xff0c;用于获取原始列表的子列表 方法的声明如下 List<E> subList(int fromIndex, int toIndex);fromIndex&#xff1a;起始索引&#xff08;包括&#xff09;toIndex&#xff1a;结束索引&#xff08…

SpringMVC学习与开发(四)

注&#xff1a;此为笔者学习狂神说SpringMVC的笔记&#xff0c;其中包含个人的笔记和理解&#xff0c;仅做学习笔记之用&#xff0c;更多详细资讯请出门左拐B站&#xff1a;狂神说!!! 11、Ajax初体验 1、伪造Ajax 结果&#xff1a;并未有xhr异步请求 <!DOCTYPE html> &…

NXP实战笔记(一):基于RTD-SDK新建一个S32DS工程

目录 1、概述 2、操作步骤 2.1、新建Application工程 2.2、命名工程、选择芯片型号、选择编译器GCC版本 2.3、配置基本参数 3、文件描述 3.1、文件结构描述 3.2、编译之后 4、下载调试 1、概述 安装了S32DS之后&#xff0c;导入SDK插件&#xff0c;这个步骤不赘述&…

R统计学1 - 基础操作入门问题1-20

R统计学入门基础问题 1. 如何生成100个高斯&#xff08;正态&#xff09;分布随机数 x <- rnorm(100, mean 5, sd 0.1) x # [1] 4.893534 5.046611 5.081097 4.979164 5.181700 5.038192 5.135376 5.173346 4.968877 4.986146 # [11] 4.946258 5.198199 5.055531 4.9430…

LSTM中文新闻分类源码详解

LSTM中文新闻分类 一、导包二、读取数据三、数据预处理1.分词、去掉停用词和数字、字母转换成小写等2.新闻文本标签数值化 三、创建词汇表/词典1.data.Field()2.空格切分等3.构建词汇表/词典使用训练集构建单词表&#xff0c;vectorsNone:没有使用预训练好的词向量,而是使用的是…