当前位置: 首页 > article >正文

算法笔记(九)——栈

文章目录

  • 删除字符串中的所有相邻重复项
  • 比较含退格的字符串
  • 基本计算机II
  • 字符串解码
  • 验证栈序列

栈是一种先进后出的数据结构,其操作主要有
进栈、压栈(Push)
出栈(Pop)

常见的使用栈的算法题

  • 中缀转后缀
  • 逆波兰表达式求值
  • 括号匹配
  • 深度优先搜索

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

题目:删除字符串中的所有相邻重复项

在这里插入图片描述
思路

  • 用栈的思想来模拟
  • 遍历字符串,如果栈为空栈顶元素和进栈元素不相同,字符进栈
  • 否则,即栈顶元素和进栈元素相同,则pop栈顶元素
  • 但是,最后留在栈中的字符就是需要返回的,并且是逆序的,所以我们直接用原来的字符串模拟栈

C++代码

class Solution 
{
public:
    string removeDuplicates(string s) 
    {
        string res;

        for(auto ch : s)
        {
            if(res.size() && res.back() == ch) res.pop_back();
            else res.push_back(ch);
        }

        return res;
    }
};

比较含退格的字符串

题目:比较含退格的字符串

在这里插入图片描述
思路

  • 利用栈的思想,封装一个check函数来返回退格后的字符串
  • chech函数的实现:
  • 遍历字符串,如果不是#,直接加到res上;否则,如果res中没有元素,但是遇到了#,直接跳过不用pop_back()

C++代码

class Solution 
{
public:
    string check(string &s)
    {
        string res;
        for(auto ch : s)
        {
            if(ch != '#') res += ch; // 如果不是‘#’。直接加到res上
            else
            {
                if(res.size()) // 如果res中没有元素,但是遇到了‘#’,应该直接跳过不用pop_back()
                    res.pop_back();
            } 
        }
        return res;
    }
    bool backspaceCompare(string s, string t) 
    {
        return check(s) == check(t); // 检查退格后的字符串是否相等
    }
};

基本计算机II

题目:基本计算器 II

在这里插入图片描述

思路

  • 由于运算符只有('+', '-', '*', '/')这四种,我们使用一个数组来模拟栈,插入每一个数,使用一个前缀字符来进行运算符的标记,初始设为加;
  • 当操作符op遇到加减都更新,遇到乘除则与栈顶元素计算,遍历结束后,我们将栈中元素相加;

C++代码

class Solution 
{
public:
    // 1. 遇到操作符,更新操作符op;
    // 2. 遇到数字;
    //      1>. 先将数字提取到tmp中
    //      2>. 根据op分类讨论
    //        ①op == '+', tmp入栈
    //        ②op == '-', -tmp入栈
    //        ③op == '*', 直接和栈顶元素相×
    //        ④op == '/', 直接和栈顶元素相÷
    int calculate(string s) 
    {
        char op = '+';
        int i = 0, n = s.size();
        vector<int> v; // 模拟栈

        while(i < n)
        {
            if(s[i] == ' ') i++;
            else if('0' <= s[i] && s[i] <= '9')
            {
                // 数字提取到tmp中
                int tmp = 0;
                while(i < n && '0' <= s[i] && s[i] <= '9')
                    tmp = 10 * tmp + (s[i++] - '0');

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

        int res = 0;
        for(auto x : v)
        {
            res += x;
        }
        return res;
    }
};

字符串解码

题目:字符串解码

在这里插入图片描述
思路

  • 定义两个栈一个字符串、一个int变量
  • 遇到数字放入数字栈
  • 遇到[,把后面的字符串提取、放入字符串栈
  • 遇到],取出两栈顶元素解析,放入字符串栈的栈顶元素后面
  • 遇到字符, 提取字符,放入字符串栈的栈顶元素后面

C++代码

class Solution 
{
public:
    // 两个栈一个字符串、一个int变量
    // 1. 遇到数字放入数字栈;
    // 2. 遇到'[',把后面的字符串提取、放入字符串栈
    // 3. 遇到']',取出两栈顶元素解析,放入字符串栈的栈顶元素后面
    // 4. 遇到字符, 提取字符,放入字符串栈的栈顶元素后面

    string decodeString(string s) 
    {
        stack<string> ss;
        stack<int> si;
        int i = 0, n = s.size();

        ss.push("");
        while(i < n)
        {
            if(s[i] >= '0' && s[i] <= '9') 
            {
                int t = 0;
                while ('0' <= s[i] && s[i] <= '9')
                    t = 10 * t + (s[i++] - '0');

                si.push(t);
            }
            else if(s[i] == '[') 
            {
                i++;
                string t = "";
                while(s[i] >= 'a' && s[i] <= 'z')
                    t += s[i++];

                ss.push(t);
            }
            else if(s[i] == ']')
            {
                string t = ss.top();
                ss.pop();
                int j = si.top();
                si.pop();

                while(j--)
                {
                    ss.top() += t;
                }
                i++; // 跳过右括号
            }
            else
            {
                string t = "";
                while(i < n && s[i] >= 'a' && s[i] <= 'z')
                    t += s[i++];

                ss.top() += t;
            }
        }
        return ss.top();
    }
};

验证栈序列

题目:验证栈序列

在这里插入图片描述

思路

用一个栈来模拟这个过程,最后栈为空则说明相匹配,否则说明不匹配

  • i来遍历pop数组,确定要出栈的元素
  • 判断栈顶元素是否等于要出栈的元素,如果相等则出栈,并i++到下一个要出栈的元素上
class Solution 
{
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) 
    {
        stack<int> s;
        int n = popped.size();
        int i = 0; // 标志位:确定要出栈的元素
        for(auto ch : pushed)
        {
            s.push(ch);
            // 判断栈顶元素是否等于要出栈的元素,如果相等则出栈,并将标志位挪到下一个要出栈的元素上
            while(s.size() && s.top() == popped[i]) 
            {
                s.pop();
                i++;
            }
        }

        return s.empty(); 
    }
};

http://www.kler.cn/news/332739.html

相关文章:

  • 在springboot项目中实现一个定时任务执行的功能
  • 基于Springboot+Vue的小区停车场管理系统登录(含源码数据库)
  • wsl2 ubuntu 桥接以太网卡
  • git维护【.gitignore文件】
  • Microsoft 更新 Copilot AI,未來將能使用語音並看到你瀏覽的網頁
  • SpringCloud学习记录|day2
  • 手机实时提取SIM卡打电话的信令声音-(题外、插播一条广告)
  • Ubuntu安装Hadoop3.4
  • 书生大模型实战(从入门到进阶)L3-彩蛋岛-InternLM 1.8B 模型 Android 端侧部署实践
  • 常见的VPS或者独立服务器的控制面板推荐
  • 华为云LTS日志上报至观测云最佳实践
  • MFC有三个选项:MFC ActiveX控件、MFC应用程序、MFC DLL,如何选择?
  • Kotlin:2.0.20 的新特性
  • 【Spring Security】基于SpringBoot3.3.4版本②如何配置免鉴权Path
  • 昇思学习打卡营第31天|深度解密 CycleGAN 图像风格迁移:从草图到线稿的无缝转化
  • 【AUTOSAR 基础软件】COM模块详解(通信)
  • MATLAB - 机械臂手眼标定(眼在手外) - 估算固定相机相对于机器人基座的姿态
  • Python爬虫通过 Cookie 和会话管理来维持其在网站上的会话状态
  • LeetCode hot100---数组及矩阵专题(C++语言)
  • 15分钟学 Python 第37天 :Python 爬虫入门(三)