【算法】栈与模拟

devtools/2024/9/23 14:31:58/

【ps】本篇有 5 道 leetcode OJ。

目录

一、算法简介

二、相关例题

1)删除字符串中的所有相邻重复项

.1- 题目解析

.2- 代码编写

2)比较含退格的字符串

.1- 题目解析

.2- 代码编写

3)基本计算器 II

.1- 题目解析

.2- 代码编写

4)字符串解码

.1- 题目解析

.2- 代码编写

5)验证栈序列

.1- 题目解析

.2- 代码编写


一、算法简介

        栈是一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底,栈中的数据元素遵守后进先出的原则。它的插入操作叫做进栈(或进栈/入栈),插入的数据在栈顶;删除操作叫做出栈。出的数据也在栈顶。

        栈一般与模拟算法结合在一起出题,在题目中野经常充当数据的缓存容器,来帮助模拟入栈和出栈的过程以求得结果。

二、相关例题

1)删除字符串中的所有相邻重复项

1047. 删除字符串中的所有相邻重复项

.1- 题目解析

        我们用一个新字符串,对每个字符模拟入栈和出栈的过程即可,具体方式是遍历字符串,从左往右依此将字符入栈(尾插入新字符串),如果当前字符与栈顶的字符(新字符串的末尾字符)相同,就将栈顶的字符出栈(对新字符串尾删),且跳过当前字符,继续遍历下一个字符。

.2- 代码编写

class Solution {
public:string removeDuplicates(string s) {string ret;for(int i=0;i<s.size();i++){//用一个新字符串对每个字符模拟入栈和出栈的过程if(ret.size() && s[i]==ret.back())ret.pop_back();else ret+=s[i];}return ret;}
};

2)比较含退格的字符串

844. 比较含退格的字符串

.1- 题目解析

        类似的,这道题也可以用字符串来模拟入栈和出栈的过程,但与上道题不同的是,出栈的条件变成了若当前字符为 '#',入栈的条件为若当前字符不为 '#'。

.2- 代码编写

class Solution {
public:bool backspaceCompare(string s, string t) {return stackString(s)==stackString(t);}//用一个新字符串模拟入栈和出栈的过程string stackString(string& s){string st;for(auto ch:s){if(ch=='#'){if(st.size())st.pop_back();}else {st+=ch;}}return st;}
};

3)基本计算器 II

227. 基本计算器 II

.1- 题目解析

        这道题只有加减乘除四个运算,没有括号,并且每一个数都是大于等于 0 的, 这样可以大大地减少需要处理的情况。

        由于表达式里面没有括号,因此只用处理加减乘除混合运算即可,这样不需要用到双栈。根据四则运算的顺序,我们可以先计算乘除法,然后再计算加减法。由此可以得出下面的结论:

  • 当一个数前面是 ' + ' 号的时候,这⼀个数是否会被立即计算是不确定的,因此可以先入栈。
  • 当一个数前面是 ' - ' 号的时候,这⼀个数是否被立即计算也是不确定的,但是这个数已经和前面的负号绑定了,因此可以将这个数的相反数入栈。
  • 当一个数前面是 ' * ' 号的时候,这⼀个数可以立即与前面的⼀个数相乘,此时让将栈顶的元素乘上这个数;
  • 当一个数前面是 ' / ' 号的时候,这⼀个数也是可以立即被计算的,因此让栈顶元素除以这个数。

        当遍历完完整的表达式时,栈中剩余的元素之和就是最终结果。此外,这里可以用数组来模拟栈。

.2- 代码编写

class Solution {
public:int calculate(string s) {char op='+';//表达式开头没有运算符,但应默认是+号int i=0,n=s.size();vector<int> st;//用数组模拟栈while(i<n){if(s[i]==' ')i++;//跳过空格else if(s[i]>='0'&&s[i]<='9'){int tmp=0;//提取一个完整的操作数while(i<n && s[i]>='0'&& s[i]<='9'){tmp=tmp*10+(s[i++]-'0');}//按运算符处理操作数if(op=='+')st.push_back(tmp);else if(op=='-')st.push_back(-tmp);else if(op=='*')st.back()*=tmp;else if(op=='/')st.back()/=tmp;}else op=s[i++];}//累加栈中的数,即可得到结果int ret=0;for(auto x:st)ret+=x;return ret;}
};

4)字符串解码

394. 字符串解码

.1- 题目解析

        本题可以用两个栈来模拟解码的过程,其中一个栈存字符,另一个栈存数字。

        解码的顺序,是从括号内部向外部依此解码,如:3[ab2[cd]] -> 3[abcd cd] -> abcdcd abcdcd abcdcd 。

.2- 代码编写

class Solution {
public:string decodeString(string s) {stack<int> nums; //数字栈stack<string> st;//字符栈st.push("");//预留一个空字符串,以防越界访问int i=0,n=s.size();while(i<n){//提取数字放入数字栈中if(s[i]>='0'&&s[i]<='9'){int tmp=0;while(s[i]>='0'&&s[i]<='9'){tmp=tmp*10+(s[i++]-'0');}nums.push(tmp);}//遇到'[',提取字符串放入字符栈中else if(s[i]=='['){i++;string tmp;while(s[i]>='a'&&s[i]<='z'){tmp+=s[i++];}st.push(tmp);}//遇到']',解析,然后将其尾插到字符栈栈顶字符串的后面else if(s[i]==']'){string tmp=st.top();st.pop();int k=nums.top();nums.pop();while(k--){st.top()+=tmp;}i++;}//提取字符串,直接尾插到字符栈栈顶字符串的后面else{string tmp;while(i<n && s[i]>='a'&& s[i]<='z'){tmp+=s[i++];}st.top()+=tmp;}}return st.top();}
};

5)验证栈序列

946. 验证栈序列

.1- 题目解析

        这是一道经典的栈相关的题目,给定一个进栈序列,再给定一个出栈序列,要求根据进栈序列判断出栈序列是否合法。

        我们可以创建一个栈,然后分别遍历这两个序列,来模拟进栈和出栈的过程。遍历进栈序列的时候,先将序列中的元素依此 push 入栈,再遍历出栈序列中的元素,如果当前元素与刚入栈的这个元素相同,那么就将其出栈,如果不是,就继续对进栈序列中的元素进行入栈,直到遇到出栈序列中的相同元素再出栈。如此,遍历完两个序列后,如果栈为空,则说明栈序列是合法的。

.2- 代码编写

class Solution {
public:bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {stack<int> st;int i=0;for(auto x:pushed){st.push(x);while(st.size()&&st.top()==popped[i]){st.pop();i++;}}return st.empty();}
};


http://www.ppmy.cn/devtools/112912.html

相关文章

网传阿里云盘出现bug,可看到其他用户云盘图片

9月14日消息称&#xff0c;阿里云盘被曝出存在一个“灾难级的严重 bug”。有用户偶然发现&#xff0c;在阿里云盘的相册功能中&#xff0c;只要创建一个文件夹&#xff0c;然后在分类选择图片这一操作下&#xff0c;竟然可以看到其他用户云盘里的图片。 目前&#xff0c;阿里云…

《JavaEE进阶》----16.<Mybatis简介、操作步骤、相关配置>

本篇博客讲记录&#xff1a; 1.回顾MySQL的JDBC操作 2..Mybatis简介、Mybatis操作数据库的步骤 3.Mybatis 相关日志的配置&#xff08;日志的配置、驼峰自动转换的配置&#xff09; 前言 之前学习应用分层时我们知道Web应用程序一般分为三层&#xff0c;Controller、Service、D…

Spring Boot-版本兼容性问题

Spring Boot 版本兼容性问题探讨 Spring Boot 是一个用于构建微服务和现代 Java 应用的流行框架&#xff0c;随着 Spring Boot 版本的更新和发展&#xff0c;它在功能、性能和安全性上不断提升。但与此同时&#xff0c;Spring Boot 的版本兼容性问题也逐渐成为开发者必须关注的…

Linux 入门:简单的基础操作

“批判他人总是想的太简单 剖析自己总是想的太困难” 文章目录 前言Linux 入门&#xff1a;从基础操作到 WSL2 安装文章有误敬请斧正 不胜感恩&#xff01;1. 什么是 Linux&#xff1f;2. Linux 和其他系统有啥不同&#xff1f;3. Linux 的主要组成4. 常见 Linux 发行版5. 基本…

【系统架构设计师】原型模式详解

原型模式详解 1. 什么是原型模式? 原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制已有的对象来创建新的对象,而不是通过类实例化来创建新对象。通过这种方式,原型模式能够减少创建对象的开销,尤其是当对象的创建过程非常复杂或者耗费资源时。原型模…

Leetcode 3291. Minimum Number of Valid Strings to Form Target I

Leetcode 3291. Minimum Number of Valid Strings to Form Target I 1. 解题思路2. 代码实现 题目链接&#xff1a;3291. Minimum Number of Valid Strings to Form Target I 1. 解题思路 这一题第一反应就是用一个字典树动态规划的方式&#xff0c;倒是也搞定了&#xff0c…

Spring6学习笔记4:事务

1 JdbcTemplate 1.1 简介 Spring 框架对 JDBC 进行封装&#xff0c;使用 JdbcTemplate 方便实现对数据库操作 准备工作 ①搭建子模块 搭建子模块&#xff1a;spring-jdbc-tx ②加入依赖 <dependencies><!--spring jdbc Spring 持久化层支持jar包--><dep…

拥有一个你说了算的人生—觉知

觉知&#xff0c;是最大的容器 觉知的力量 觉知&#xff0c;必然意味着对自身的了解&#xff0c;并且还会伴随着深刻的体验 觉知是光&#xff0c;而没有被觉知之物&#xff0c;就藏在黑暗中。一旦有觉知之光照进来&#xff0c;黑暗不仅无所遁形&#xff0c;而且黑暗中的动力还…