【力扣题目分享】栈专题(C++)

目录

关于栈的题目:

1. 最小栈:

 思路:

实现代码(最终): 

2. 栈的压入、弹出序列:

思路:

实现代码:

 3. 逆波兰表达式求值:

思路:

实现代码:

深入了解逆波兰表达式: 

实现代码: 

用栈实现队列 

思路: 

实现代码:


学了栈却不知道该怎么用于做题?本篇将分享几道栈相关的经典题目

关于栈的题目:

1. 最小栈:

 思路:

先拿示例一举例,我们可以定义两个栈,st和min

st用来存push进去的数据,而min用来存当前st中数据的最小值,具体怎么实现呢?模拟一下示例1

 实现代码:

class MinStack {
public:/** initialize your data structure here. */MinStack() {//这里可以不用写,会调用默认的构造函数}void push(int x) {st.push(x);//先入普通的栈if(min.empty() || x<min.top())//如果这个数据小于等于最小栈中栈顶的数据,就插入,让x成为新的最小值min.push(x);}void pop() {if(st.top() == min.top())//如果要删除的数和最小栈的栈顶的值相同,就代表要删除的这个数也是现在栈中最小的数,所以要把最小栈中的那个数也pop掉min.pop();st.pop();}int top() {return st.top();//取普通栈的栈顶}int getMin() {return min.top();//取最小栈的栈顶}
private:stack<int> st;//普通用来存数据的栈stack<int> min;//用来存每一时期的最小值(栈顶就是当前时期的最小值)
};

但如果运行的话会报错

那我们就用这组出错的数据再模拟一下

所以在第三步时(即插入第二个0)也应将0入栈min 

这样即使再getmin,值也还会是0

实现代码(最终): 

class MinStack {
public:/** initialize your data structure here. */MinStack() {//这里可以不用写,会调用默认的构造函数}void push(int x) {st.push(x);//先入普通的栈if(min.empty() || x<min.top())//如果这个数据小于等于最小栈中栈顶的数据,就插入,让x成为新的最小值min.push(x);}void pop() {if(st.top() == min.top())//如果要删除的数和最小栈的栈顶的值相同,就代表要删除的这个数也是现在栈中最小的数,所以要把最小栈中的那个数也pop掉min.pop();st.pop();}int top() {return st.top();//取普通栈的栈顶}int getMin() {return min.top();//取最小栈的栈顶}
private:stack<int> st;//普通用来存数据的栈stack<int> min;//用来存每一时期的最小值(栈顶就是当前时期的最小值)
};

2. 栈的压入、弹出序列:

思路:

 先定义一个栈,用来模拟入栈出栈

 到下一次入栈时,此时st.pop() == pop[i],所以就要开始出栈,直到st.pop() != pop[i]为止

出栈4后,现在的数据是这样 

所以要继续入栈

 删除完最后一个数据之后

实现代码:

bool IsPopOrder(vector<int>& pushV, vector<int>& popV) 
{stack<int> st;//创建一个栈,用来存pushV的数据int popi = 0;//popV的进度for(int i=0;i<pushV.size();i++)//每次都入栈pushV的数据{st.push(pushV[i]);while(!st.empty() && st.top() == popV[popi])//如果现在栈顶的数据等于popV进度的数据,就表示需要开始出栈了{st.pop();popi++;}}return st.empty();//如果最后栈里没有数据了,就代表全pop完了,就是对的
}

 3. 逆波兰表达式求值:

思路:

逆波兰表达式,也叫后缀表达式,我们平常用的表达式是中缀表达式,例如a+b,写成后缀表达式就是ab+,即把操作符放到了数的后面,这是为了优先级的区分(更便于计算),优先级越高的操作符就会越在前面

(a+b)*c-(a+b)/e转换成后缀表达式就是ab+c*ab+e/-,即先让"a"和"b"执行"+"操作,然后让"a+b"的值和"c"执行"*"操作,再让"a"和"b"执行"+"操作,以此类推

 相信对栈有一定了解的人都已经想到了,这道题可以用栈模拟的方法轻松解决

遇到非操作符就入栈,遇到操作符就把栈的前两个元素出栈并运算,运算完把结果再入栈就可以

 具体点来说,拿示例1模拟

示例二模拟:

 

可以看到,最后存在栈(栈顶)的数据就是最终结果

实现代码:

int evalRPN(vector<string>& tokens) 
{stack<int> st;//用一个栈来模拟数运算的先后顺序int i=0;while(i < tokens.size())//遍历数组{if(tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/")//如果不是算数符就入栈st.push(stoi(tokens[i]));else//遇到算数符,就把栈的前两个元素提出来(第一个提出来的是右元素,第二个是左元素){int right = st.top();st.pop();int left = st.top();st.pop();switch(tokens[i][0])//判断是哪个算术符{case '+':st.push(left+right); break;case '-':st.push(left-right); break;case '*':st.push(left*right); break;case '/':st.push(left/right); break;}}i++;}return st.top();
}

深入了解逆波兰表达式: 

注:面试时一般不会考的这么深入,如果有兴趣可以看看这部分内容

本题中给出的输入就已经是逆波兰表达式了,那中缀表达式是如何转换成逆波兰表达式(后缀表达式)的呢

例如,我们有一个中缀表达式1+2*4+3,根据优先级,它会先算2*4,再拿2*4的结果去算另外两个加式,但如果直接这样计算的话,不避免的会先算加法式,所以要给它转换成后缀表达式后用栈的特性来计算

转换成后缀表达式也需要用栈,下面来模拟一下过程

规则:

  1. 遇到数字,提出来(尾插到后缀表达式中)
  2. 遇到操作符,若此时栈为空,就入栈
  3. 遇到操作符,若此时栈不为空,如果当前操作符比栈顶的操作符优先级要高,就入栈
  4. 遇到操作符,若此时栈不为空,如果当前操作符比栈顶的操作符优先级要低或相等,就出栈掉相等的操作符(直到栈顶为空或比栈顶的优先级要低),并将出栈的操作符尾插到后缀表达式中,然后再入栈新操作符

实现代码: 
#include <iostream>
#include <string>
#include <vector>
#include <stack>
using namespace std;bool op(string s)//判断是否为操作符
{if(s=="+"||s=="-"||s=="*"||s=="/")return true;elsereturn false;
}int priority(string s)//返回该操作符的优先级比
{if(s == "+" || s == "-")return 1;else return 2;
}
int main()
{vector<string> infix = {"1","+","2","*","4","+","3"};//待转换的中缀表达式vector<string> postfix;//待尾插的后缀表达式stack<string> st;//存操作符的栈for(int i=0;i<infix.size();i++){if(op(infix[i]))//如果该位置是操作符{if(st.empty() || priority(st.top()) < priority(infix[i]))//如果栈为空或者栈顶的优先级比当前操作符低,则直接入栈{st.push(infix[i]);}else//否则栈顶的优先级比当前操作符高或相等,则将栈顶的操作符弹出,直到栈顶的优先级比当前操作符低,然后将当前操作符入栈{while(!st.empty() && priority(st.top()) >= priority(infix[i])){string s = st.top();st.pop();postfix.push_back(s);}st.push(infix[i]);}}else//如果该位置是操作数,则直接尾插到后缀表达式中{postfix.push_back(infix[i]);}}while(!st.empty())//将栈中剩余的操作符弹出并尾插到后缀表达式中{string s = st.top();st.pop();postfix.push_back(s);}for(const auto& s : postfix){cout << s << " ";}return 0;
}

输出结果:

用栈实现队列 

思路: 

 众所周知,栈是后进先出(LIFO),而队列是先进先出(FIFO),想用两个栈实现先进先出,可以用一个栈专门入数据,另外一个栈专门出数据

拿这个数据来举例,现在我们要出队的话,会先出1,怎么样才能先读到1呢?

再把数据全部都入到另外一个栈上,此时出栈的顺序就和出队一样了

当然,还有很多细节没有处理

只要要出栈时才会用到popst,所以只有要出栈时,才需要把pushst中的数据都入到popst中

并且,当popst中有数据时,就先不用把pushst中的数据入到popst,因为此时如果再入的话popst栈顶的数据就不是先进的那个数了

实现代码:

class MyQueue {
public:MyQueue() {//让它调用默认的构造函数就行(stack的构造函数)}void push(int x) {//往pushst中插入数据pushst.push(x);}//先在pushst中插入数据,这样再一个个出栈到popst时,再popst.top()就是队尾的数据了int pop() {if(popst.empty())//如果此时popst还是空的,就得先给popst数据{while(!pushst.empty()){int tmp = pushst.top();pushst.pop();popst.push(tmp);}}int x = popst.top();popst.pop();return x;}int peek() {if(popst.empty())//如果此时popst中没有数据,就要先把pushst的数据给popst{while(!pushst.empty()){int tmp = pushst.top();pushst.pop();popst.push(tmp);}}return popst.top();}bool empty() {//只有两个栈里都没有数据才是真没数据return pushst.empty() && popst.empty();}
private:stack<int> pushst;//负责入栈stack<int> popst;//负责出栈
};

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

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

相关文章

Office 2019 (含Visio+Project)官方IOS 下载

Microsoft Office 2019 是微软公司推出的一款办公软件套装&#xff0c; 主要包括Word、Excel、PowerPoint、Outlook、Visio、Access、Publisher、OneDrive for Business 和Skype for Business等组件。 这些组件适用于Windows和MacOS平台&#xff0c;支持多种语言&#xff0c…

遥测终端机,推动灌区流量监测向数据驱动跃迁

灌区范围那么大&#xff0c;每一滴水怎么流都关系到粮食够不够吃&#xff0c;还有生态能不能平衡。过去靠人工巡查、测量&#xff0c;就像拿着算盘想算明白大数据&#xff0c;根本满足不了现在水利管理的高要求。遥测终端机一出现&#xff0c;就像给灌区流量监测安上了智能感知…

P4017 最大食物链计数-拓扑排序

P4017 最大食物链计数 题目来源-洛谷 题意 要求最长食物链的数量。按照题意&#xff0c;最长食物链就是指有向无环图DAG中入度为&#xff10;到出度为&#xff10;的不同路径的数量&#xff08;链数&#xff09; 思路 在计算时&#xff0c;明显&#xff1a;一个被捕食者所…

Xmind快捷键大全

常规 插入主题和元素&#xff08;常用&#xff09; 编辑主题文本和样式 选择和移动 调整画布和视图 工具和其他

四. 以Annoy算法建树的方式聚类清洗图像数据集,一次建树,无限次聚类搜索,提升聚类搜索效率。(附完整代码)

文章内容结构&#xff1a; 一. 先介绍什么是Annoy算法。 二. 用Annoy算法建树的完整代码。 三. 用Annoy建树后的树特征匹配聚类归类图像。 一. 先介绍什么是Annoy算法 下面的文章链接将Annoy算法讲解的很详细&#xff0c;这里就不再做过多原理的分析了&#xff0c;想详细了解…

什么是电容?

什么是电容&#xff1f; 电荷与电压的比值就是电容量C。电容单位为法拉(F)。1法拉电容器在电压为1V时储存的电荷量为1库伦(C)。图1.1中的球体表面电压与储存的电荷Q关联。电压V等于。Q/V等于。如果球体位于电介质媒介中&#xff0c;电压V降低倍&#xff0c;Q/V等于。在电介质媒…

Linux服务器上mysql8.0+数据库优化

1.配置文件路径 /etc/my.cnf # CentOS/RHEL /etc/mysql/my.cnf # Debian/Ubuntu /etc/mysql/mysql.conf.d/mysqld.cnf # Ubuntu/Debian检查当前配置文件 sudo grep -v "^#" /etc/mysql/mysql.conf.d/mysqld.cnf | grep -v "^$&q…

MQTT学习资源

MQTT入门&#xff1a;强烈推荐

第十二章 Python语言-大数据分析PySpark(终)

目录 一. PySpark前言介绍 二.基础准备 三.数据输入 四.数据计算 1.数据计算-map方法 2.数据计算-flatMap算子 3.数据计算-reduceByKey方法 4.数据计算-filter方法 5.数据计算-distinct方法 6.数据计算-sortBy方法 五.数据输出 1.输出Python对象 &#xff08;1&am…

【XR手柄交互】Unity 中使用 InputActions 实现手柄控制详解(基于 OpenXR + Unity新输入系统(Input Actions))

摘要&#xff1a; 本文主要介绍如何使用 Input Actions&#xff08;Unity 新输入系统&#xff09; OpenXR 来实现 VR手柄控制&#xff08;监听ABXY按钮、摇杆、抓握等操作&#xff09;。 &#x1f3ae; Unity 中使用 InputActions 实现手柄控制详解&#xff08;基于 OpenXR 新…

java实现网格交易回测

以下是一个基于Java实现的简单网格交易回测程序框架&#xff0c;以证券ETF&#xff08;512880&#xff09;为例。代码包含历史数据加载、网格策略逻辑和基础统计指标&#xff1a; import java.io.BufferedReader; import java.io.FileReader; import java.text.ParseException…

探秘 3D 展厅之卓越优势,解锁沉浸式体验新境界

&#xff08;一&#xff09;打破时空枷锁&#xff0c;全球触达​ 3D 展厅的首要优势便是打破了时空限制。在传统展厅中&#xff0c;观众需要亲临现场&#xff0c;且必须在展厅开放的特定时间内参观。而 3D 展厅依托互联网&#xff0c;让观众无论身处世界哪个角落&#xff0c;只…

第十二届蓝桥杯 2021 C/C++组 直线

目录 题目&#xff1a; 题目描述&#xff1a; 题目链接&#xff1a; 思路&#xff1a; 核心思路&#xff1a; 两点确定一条直线&#xff1a; 思路详解&#xff1a; 代码&#xff1a; 第一种方式代码详解&#xff1a; 第二种方式代码详解&#xff1a; 题目&#xff1a;…

微信小程序蓝牙连接打印机打印单据完整Demo【蓝牙小票打印】

文章目录 一、准备工作1. 硬件准备2. 开发环境 二、小程序配置1. 修改app.json 三、完整代码实现1. pages/index/index.wxml2. pages/index/index.wxss3. pages/index/index.js 四、ESC/POS指令说明五、测试流程六、常见问题解决七、进一步优化建议 下面我将提供一个完整的微信…

ubuntu opencv 安装

1.ubuntu opencv 安装 在Ubuntu系统中安装OpenCV&#xff0c;可以通过多种方式进行&#xff0c;以下是一种常用的安装方法&#xff0c;包括从源代码编译安装。请注意&#xff0c;安装步骤可能会因OpenCV的版本和Ubuntu系统的具体版本而略有不同。 一、安装准备 更新系统&…

【C++】class静态常量

Usage: static const T 1 background static const成员属于类&#xff0c;而不是类的实例&#xff0c;所以它们的初始化需要在类外进行(或者在C17之后可以用inline初始化)。 使用中可能遇到的情况&#xff1a; 在头文件中声明一个static const成员&#xff0c;然后在多个cpp…

Java 安全:如何防止 DDoS 攻击?

一、DDoS 攻击简介 DDoS&#xff08;分布式拒绝服务&#xff09;攻击是一种常见的网络攻击手段&#xff0c;攻击者通过控制大量的僵尸主机向目标服务器发送海量请求&#xff0c;致使服务器资源耗尽&#xff0c;无法正常响应合法用户请求。在 Java 应用开发中&#xff0c;了解 …

统计文件中单词出现的次数并累计

# 统计单词出现次数 fileopen("E:\Dasktape/python_test.txt","r",encoding"UTF-8") f1file.read() # 读取文件 countf1.count("is") # 统计文件中is 单词出现的次数 print(f"此文件中单词is出现了{count}次")# 2.判断单词出…

C语言实现贪心算法

一、贪心算法核心思想 特征&#xff1a;在每一步选择中都采取当前状态下最优&#xff08;局部最优&#xff09;的选择&#xff0c;从而希望导致全局最优解 适用场景&#xff1a;需要满足贪心选择性质和最优子结构性质 二、经典贪心算法示例 1. 活动选择问题 目标&#xff1a…

《一文读懂Transformers库:开启自然语言处理新世界的大门》

《一文读懂Transformers库:开启自然语言处理新世界的大门》 GitHub - huggingface/transformers: 🤗 Transformers: State-of-the-art Machine Learning for Pytorch, TensorFlow, and JAX. HF-Mirror Hello! Transformers快速入门 pip install transformers -i https:/…