【算法】使用栈解决一系列算法题(匹配、表达式、模拟)(C++)

news2024/11/18 20:19:30

1. 前言(栈适用于解哪些题?)

栈适合解决需要后进先出(LIFO)的结构的算法题,例如:

  1. 括号匹配问题:判断给定字符串中括号是否匹配。
  2. 表达式求值问题:将表达式转换为后缀表达式,并计算其值。
  3. 逆波兰表达式问题:将表达式转换为逆波兰表达式,并计算其值。
  4. 直方图最大矩形面积问题:给定一个直方图,求最大的矩形面积。
  5. 进制转换问题:将一个十进制数转换为任意进制的数。
  6. 迷宫问题:在迷宫中寻找从起点到终点的路径。

我们下面会选择一部分题并用栈来进行解题:

2. 算法题

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

在这里插入图片描述

思路

  • 题意分析:要求将字符串中所有连续的字符删去,如下图所示:
    在这里插入图片描述

  • 解法用栈模拟这个过程

    • 创建一个string类来作为栈
    1. 将s中的元素依次入栈,每次判断站栈顶元素是否等于当前元素
    2. 如果是,则删去栈顶元素,如果不是则将该元素入栈

代码

string removeDuplicates(string s) {
   // 解法:用栈模拟过程
    string st;
    for(char ch : s)
    {
        if(!st.empty() && st.back() == ch)
            st.pop_back();
        else
            st += ch;
    }

    return st;
}

844.比较含退格的字符串

在这里插入图片描述

思路

  • 题意分析:即比较两个字符串在退格后是否相同,
  • 解法用栈模拟这个过程
    1. 分别对两个字符串创建栈来模拟(用字符串表示栈)
    2. 如果 遇到#且栈不为空,则删除栈顶元素,否则将当前元素入栈。

代码

bool backspaceCompare(string s, string t) {
    // 栈模拟退格删除元素过程
    string st1 = "";
    for(char ch : s)
    {
        if(ch != '#')
            st1.push_back(ch);
        else if(ch == '#' && !st1.empty())
            st1.pop_back();
    }

    string st2 = "";
    for(char ch : t)
    {
        if( ch != '#')
            st2.push_back(ch);
        else if(ch == '#' && !st2.empty())
            st2.pop_back();
    }

    return st1 == st2;
}

227.基本计算器II

在这里插入图片描述

思路

  • 题意分析:该题属于一个表达式求值题,即计算一个表示表达式的字符串的值。该题中s仅由’+‘、’-‘、’*‘、’/’ 四个符号组成。

  • 解法利用栈进行计算(数组表示栈)
    在这里插入图片描述

    • 上面的是使用栈解决这道题的总体算法思想,下面是步骤细节注意.
    1. 定义sym用于记录符号字符,数组表示栈
    2. 从头遍历字符串,根据当前字符进入不同分支
      • 如果是空格,直接跳过该位,i++
      • 如果是符号,则sym记录当前符号后,i++
      • 如果是数字
        • 由于表达式中的数不一定是个位数,所以先利用循环找到当前位置的数
    3. 之后根据sym存储的符号对tmp和栈顶元素进行处理(即图中步骤)
    4. 最后累加元素

代码

int calculate(string s) {
    // 用一个栈存储数字字符,定义sym记录遇到的符号
    // sym='+' : 直接将下一位tmp加到栈中
    // sym='-' : 将-tmp加入到栈中
    // sym='*' : 栈顶元素 *= tmp
    // sym='/' : 栈顶元素 /= tmp
    char sym = '+';
    vector<int> st; // 数组作栈
    int i = 0, n = s.size();
    while(i < n)
    {
        if(s[i] == ' ') i++;
        else if(s[i] >= '0' && s[i] <= '9')
        {
            int tmp = 0;
            while(s[i] >= '0' && s[i] <= '9')
            	// 循环:tmp记录当前数字 并将其由字符串转为整形)
                tmp = tmp * 10 + (s[i++] - '0');

            if(sym == '+') st.push_back(tmp);
            else if(sym == '-') st.push_back(-tmp);
            else if(sym == '*') st.back() *= tmp;
            else st.back() /= tmp;
        }
        else
        {
            sym = s[i++];
        }
    }

    int ret = 0;
    // 将栈中所有元素累加
    for(auto x : st)
        ret += x;

    return ret;
}

394.字符串解码

在这里插入图片描述

思路

  • 题意分析:看示例便很好理解,通过将 “数字[字符]” 解码为 “数字次字符串

  • 解法利用栈进行计算/font>
    在这里插入图片描述

    • 上图为用栈解决该题的总体算法思路,下面是简单的部分注意事项
    • 遇到 ‘[’ 时,我们向 “字符串栈” 加入空串,便于后面的字符串加入到"字符串栈"中
    • 最后结果就是字符串的栈顶元素

代码

string decodeString(string s) {
    // 栈模拟过程 : 字符串栈sst 整形栈 ist
    vector<string> sst;
    sst.push_back(""); // 初始化栈顶元素为空串
    vector<int> ist;
    // 遍历字符串,四种情况:
    // 1. 遇到数字:放入ist
    // 2. 遇到字符串 : 放到sst栈顶元素的后一位
    // 3. 遇到左括号 : 将空字符串 "" 加入到 sst 的栈顶
    // 4. 遇到右括号 : 合并两栈栈顶元素(即重复字符串)
    int i = 0, n = s.size();
    string tmp = "";
    while(i < n)
    {
        if(s[i] >= '0' && s[i] <= '9')
        {
            int num = 0;
            // 数字并不一定是个位、
            while(isdigit(s[i]))
                num = num * 10 + (s[i++] - '0');
            ist.push_back(num);
            continue;
        }
        else if(s[i] >= 'a' && s[i] <= 'z')
        {
            tmp = "";
            while(s[i] >= 'a' && s[i] <= 'z' && i < n)
                tmp += s[i++]; // 记录该字符串
            sst[sst.size() - 1] += tmp; // 加到栈顶后一位
            continue;
        }
        else if(s[i] == '[')
        {
            sst.push_back(""); // 新建空串
        }
        else // s[i] == ']'
        {
            // 合并两栈顶元素(重复字符串)
            tmp = sst.back();
            int x = ist.back();
            ist.pop_back();
            sst.pop_back();
            while(x--)
                sst.back() += tmp;
        }
        ++i;
    }

    return sst.back();
}

946.验证栈序列

在这里插入图片描述

思路

  • 题意分析:标准的用栈模拟过程的题,即根据题目给出的pushed和poped数组来判断该输入、弹出顺序是否合法。
  • 解法利用栈模拟过程
    1. 定义两指针分别表示当前待入栈元素的位置和当前要弹出的元素在出栈序列中的位置
    2. 进入循环,判断当前的状态是否合法
      • 合法则将该元素弹出栈
      • 不合法则将当前待入栈元素压入辅助栈中,并将cur1指针后移
    3. 当所有的元素都入栈之后,如果辅助栈中还有元素,说明出栈序列不合法

代码

bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
    stack<int> st; // 辅助栈
    int cur1 = 0, cur2 = 0;
    while (cur2 < popped.size()) 
    {   // 出栈序列结束,则合法
        if (!st.empty() && st.top() == popped[cur2]) 
        {
            st.pop();
            cur2++;
        }
        else if (cur1 < pushed.size())
            st.push(pushed[cur1++]);
        else
            return false;
    }
    return true;
}

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

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

相关文章

for循环判断有几个偶数

num100 count0 for i in range(1,num):if i%20:print("为偶数")count1 print(f"1-100的范围内&#xff0c;有{count}个偶数") 运行结果如下&#xff1a;

全罐喂养一个月多少钱?适合猫咪全罐喂养的性价比猫罐头推荐

许多铲屎官为了防止他们的猫养成挑食的习惯并确保均衡的营养摄入&#xff0c;正考虑采用全罐喂养的方式。然而&#xff0c;他们也担忧全罐喂养会带来高昂的开销。那么&#xff0c;全罐喂养一个月多少钱呢&#xff1f; 放心&#xff0c;作为一位有6年宠物店经营经验的店长&…

基于ArcGIS的晕线制作

在借助ArcGIS进行制图时&#xff0c;我们有时需要为矢量边界添加晕线&#xff0c;今天就来探索一下基于ArcGIS的晕线制作操作。 软件版本&#xff1a;ArcMap10.4.1 方法一&#xff1a;制作多环缓冲区 工具路径&#xff1a;Analysis Tools-Proximity-Mutiple Ring Buffer 思…

C++写二进制文件

源文件 #include <iostream> #include <fstream> #include <sstream> #include <cmath>void convert2() {// 打开输入文本文件std::ifstream inputFile("mask.txt");// 打开输出二进制文件std::ofstream outputFile("mask.dat", …

软件测试|使用Python读写yaml文件,你会了吗?

简介 YAML&#xff08;YAML Aint Markup Language&#xff09;是一种可读的数据序列化格式&#xff0c;它常用于配置文件和数据交换。Python 提供了许多库来处理 YAML 文件。在本文中&#xff0c;我们将探讨如何使用 PyYAML 库来读取和写入 YAML 文件&#xff0c;以及提供一些…

CentOS 7 权限管理实战指南:用户管理相关命令详解

前言 掌握 CentOS 7 用户管理命令&#xff0c;轻松管理系统用户&#xff01;本文详细介绍了在 CentOS 7 系统中常用的用户管理命令&#xff0c;从创建和删除用户、修改用户属性&#xff0c;到密码管理和用户权限设置&#xff0c;一应俱全。无论你是 Linux 新手还是经验丰富的管…

huggingface学习 | 云服务器使用git-lfs下载huggingface上的模型文件

文章目录 一、找到需要下载的huggingface文件二、准备工作&#xff08;一&#xff09;安装git-lfs&#xff08;二&#xff09; 配置git ssh 三、检查ssh连接huggingface是否成功 一、找到需要下载的huggingface文件 huggingface官网链接&#xff1a;https://huggingface.co/ 以…

rime中州韵小狼毫 LaTex输入法配置

教程目录&#xff1a;rime中州韵小狼毫须鼠管安装配置教程 保姆级教程 100增强功能配置教程 本文的分享一种在rime中州韵小狼毫须鼠管输入法中配置LaTex输入方案的方法&#xff0c;并不完美&#xff0c;仅供参考。 先睹为快 LaTex输入方案可以快捷的在公式模式下输入一些基础…

猫咪全罐喂养一个月多少钱?适合给猫咪全罐喂养的猫罐头推荐

不少铲屎官为了防止猫咪挑食和营养吸收不均衡&#xff0c;打算给猫咪进行全罐喂养&#xff0c;但是又担心全罐喂养花费太多钱了。猫咪全罐喂养一个月多少钱&#xff1f;别担心&#xff0c;咱们打工人的养猫攻略&#xff0c;花小钱办大事&#xff01;追求高性价比的猫罐头才是王…

软件测试|使用selenium处理单选框和多选框

简介 我们在web自动化测试工作中&#xff0c;经常会遇到对单选框&#xff08;Radio Buttons&#xff09;或者多选框&#xff08;Checkboxes&#xff09;进行操作的场景&#xff0c;单选框和多选框主要是用于我们做出选择或提交数据。本文将主要介绍selenium对于单选框和多选框…

嵌入式新人要坚持嵌入式吗?

今日话题&#xff0c;嵌入式新人要坚持嵌入式吗?这问题让我想起了我大学时学习嵌入式的经历。当时&#xff0c;学校还发了一些开发板&#xff0c;可惜我自己的学习进展不顺利&#xff0c;最终我决定转向了纯软件开发领域。但是&#xff0c;我大学时有一个同学&#xff0c;他一…

Flink启动Yarn Session报错:Couldn‘t deploy Yarn session cluster

Flink版本&#xff1a;1.1.3 启动Yarn Session的语句&#xff1a;bin/yarn-session.sh -nm test -d 报错截图如下&#xff1a; 仅通过ERROR信息只能知道是yarn session集群未能正常启动&#xff0c;因此继续向下查找&#xff1a; 找到报错信息的Caused by部分&#xff1a; 报…

网络原理--http

目录 一、 DNS&#xff08;应用层协议&#xff09; 1、域名概念 2、维护ip地址和域名之间的映射&#xff08;域名解析系统&#xff09; 3、DNS系统&#xff08;服务器&#xff09; 4、如何解决DNS服务器高并发问题 二、HTTP&#xff08;应用层协议&#xff09; 1、htt…

觉得做文档不被重视?来看看你未来的可能性

▲ 搜索“大龙谈智能内容”关注公众号▲ 在《2023中国技术传播行业调研报告》中&#xff0c;“从业者心中的痛”这项调研的统计如下图。 其中&#xff0c;“企业内高层不够重视”排在第一位。 图1 - “从业者心中的痛”统计 对于行业的发展趋势&#xff0c;大家是这样看的…

海外代理IP怎么用?常见使用问题及解决方案

海外代理IP是指提供全球范围内的代理服务器&#xff0c;代理服务器充当IP与目标网站之间的中介&#xff0c;可以起到安全匿名、提高网速、突破网络壁垒的作用。在使用代理IP的过程中&#xff0c;用户可能会遇到各种挑战&#xff0c;如连接问题、速度慢等。理解这些问题的原因并…

计算机导论06-人机交互

人机交互基础 人机交互概述 人机交互及其发展 人机交互是指人与计算机之间&#xff0c;使用某种对话语言&#xff0c;以一定的交互方式&#xff0c;为完成确定任务的信息交换过程。 从计算机的诞生之日起&#xff0c;人机交互技术的发展已经历了以下阶段&#xff1a; 早期的…

Linux 有哪些搜索方式?5分钟带你搞懂!

5分钟带你掌握 Linux 的三种搜索方式 前言 1.find 命令 find 命令是用来在给定的目录下查找符合给定条件的文件 语法格式&#xff1a;find [查找起始路径] [查找条件] [处理动作] &#xff08;1&#xff09;根据名称查找&#xff1a;find [查找起始路径] -name 文件名 或者…

开源云真机平台-Sonic平台-python自定义脚本-config.ini方式实现全局配置参数的读写操作

【主要功能】 config.ini方式实现全局配置参数的读写操作 使用python实现以下功能&#xff1a; 1、使用将接口获取的变量值&#xff0c;写入到当前目录下的config文件中&#xff0c;如delayTime10&#xff1b; 2、读取当前目录下的config文件中&#xff0c;特定变量的值&…

【Java】equals和hashCode需要一起重写的原因

方法实现&#xff1a; equals和hashCode两个方法是属于Object基类的两个方法&#xff0c;我们先来看看两个方法的默认实现。 equals方法&#xff1a; public boolean equals(Object obj) {return (this obj);} 可以看到equals方法的默认实现是使用 比较两个对象&#xff0c…

Selenium使用指南(超详细)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 概述 selenium是网页应用中最流行的自动化测试工具&#xff0c…