首页 > 编程语言 >代码随想录算法训练营第11天 | 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值

代码随想录算法训练营第11天 | 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值

时间:2023-01-09 00:33:21浏览次数:61  
标签:11 遍历 括号 元素 随想录 st tokens 字符串 求值

20. 有效的括号

文章:代码随想录 (programmercarl.com)

视频:栈的拿手好戏!| LeetCode:20. 有效的括号_哔哩哔哩_bilibili

思路:

先来分析一下 这里有三种不匹配的情况,

  1. 第一种情况,字符串里左方向的括号多余了 ,所以不匹配。 括号匹配1
  2. 第二种情况,括号没有多余,但是 括号的类型没有匹配上。 括号匹配2
  3. 第三种情况,字符串里右方向的括号多余了,所以不匹配。 括号匹配3

我们的代码只要覆盖了这三种不匹配的情况,就不会出问题,可以看出 动手之前分析好题目的重要性。

20.有效括号

第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false

第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false

第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false

那么什么时候说明左括号和右括号全都匹配了呢,就是字符串遍历完之后,栈是空的,就说明全都匹配了。

class Solution {
public:
    bool isValid(string s) {
        /*
            1. 左括号多余:([{}]()  
            2. 左右括号不匹配:[{(}}]
            3. 右括号多余:[{}]())))
        */
        stack<char> st;
        //如果字符串长度为奇数,直接返回false
        if (s.size() % 2 != 0)
        {
            return false;
        }

        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(')');
            }
            /*
                如果遍历到的元素是右括号
                ① 遍历过程中栈为空 —> 3
                ② 当前遍历到的元素与栈顶元素不匹配 —> 2
            */
            else if (st.empty() || s[i] != st.top()) {
                return false;
            }
            else {
                st.pop();
            }
        }
        //如果栈为空,则所有符号都匹配成功
        //如果栈非空,则为情况一,左括号多余
        return st.empty();
    }
};

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

文章:代码随想录 (programmercarl.com)

视频:栈的好戏还要继续!| LeetCode:1047. 删除字符串中的所有相邻重复项_哔哩哔哩_bilibili

思路:

那么栈里应该放的是什么元素呢?

我们在删除相邻重复项的时候,其实就是要知道当前遍历的这个元素,我们在前一位是不是遍历过一样数值的元素,那么如何记录前面遍历过的元素呢?

所以就是用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。

然后再去做对应的消除操作。 如动画所示:

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

可以拿字符串直接作为栈,这样省去了栈还要转为字符串的操作。

//push_back():向数组或字符串的尾部添加元素
//pop_back():弹出数组或字符串尾部元素
//push_front():向数组或字符串的头部添加元素
//pop_front():弹出数组或字符串头部元素

class Solution {
public:
    string removeDuplicates(string s) {
        //使用字符串模拟栈,字符串的头部为栈底,字符串尾部为栈顶
        string result; 
        for (char c : s)
        {
            //如果结果集(栈)为空,或当前遍历元素与栈顶元素(字符串中当前字符前一位,result的串尾元素)不相等,将当前元素加到栈顶(result字符串尾部)
            if (result.empty() || c != result.back())
            {
                result.push_back(c);
            }
            //如果当前元素与栈顶元素相等,则弹出栈顶元素(字符串尾部元素)
            else {
                result.pop_back();
            }
        }
        return result;
    }
};

150. 逆波兰表达式求值

文章:代码随想录 (programmercarl.com)

视频:栈的最后表演! | LeetCode:150. 逆波兰表达式求值_哔哩哔哩_bilibili

思路:

那么来看一下本题,其实逆波兰表达式相当于是二叉树中的后序遍历。 大家可以把运算符作为中间节点,按照后序遍历的规则画出一个二叉树。

但我们没有必要从二叉树的角度去解决这个问题,只要知道逆波兰表达式是用后序遍历的方式把二叉树序列化了,就可以了。

在进一步看,本题中每一个子表达式要得出一个结果,然后拿这个结果再进行运算,那么这岂不就是一个相邻字符串消除的过程,和1047.删除字符串中的所有相邻重复项 (opens new window)中的对对碰游戏是不是就非常像了。

150.逆波兰表达式求值

                *
              /   \
             +     +
            / \   / \
           1   2 3   4
class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<long long> st;
        for (int i = 0; i < tokens.size(); i++)
        {
            //当前遍历的元素为+-*/,在栈中取出两个元素,利用该符号进行运算,将运算结果压入栈中
            if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") 
            {
                long long num1 = st.top();
                st.pop();
                long long num2 = st.top();
                st.pop();
                if (tokens[i] == "+") {
                    st.push(num2 + num1);
                }
                if (tokens[i] == "-") {
                    st.push(num2 - num1);
                }
                if (tokens[i] == "*") {
                    st.push(num2 * num1);
                }
                if (tokens[i] == "/") {
                    st.push(num2 / num1);
                }
            }
            else {
                //如果当前遍历元素为数字,将当前元素直接压入栈中
                st.push(stoll(tokens[i]));
            }
        }
        int result = st.top();
        st.pop();
        return result;
    }
};

标签:11,遍历,括号,元素,随想录,st,tokens,字符串,求值
From: https://www.cnblogs.com/chaoyue-400/p/17035827.html

相关文章

  • P1141 01迷宫
    这题数据有点高级啊(这么高级的数据能不能把它变成黄题呢?不然显得我很垃圾(虽然是事实))思路联通块,把周围四格与自己不同的联通起来,看成一个大块,知道要的坐标属于哪个大块并......
  • POJ - 1182 食物链
    POJ-1182食物链题解:种族并查集引理:对于普通的并查集,我们总是用来查找和维护每个元素之间的同类关系,而种族并查集总是用来解决一些存在对立关系,而且对象的关系存在传......
  • Vulnhub之Funbox 11 (Scriptkiddie)靶机测试过程
    Funbox11(Scriptkiddie)作者:jason_huawen靶机信息名称:Funbox:Scriptkiddie地址:https://www.vulnhub.com/entry/funbox-scriptkiddie,725/识别目标主机IP地址─(......
  • P11_组件-button和image组件的基本用法
    其它常用组件button按钮组件功能比HTML中的button按钮丰富通过open-type属性可以调用微信提供的各种功能(客服、转发、获取用户授权、获取用户信息等)image......
  • P11_组件-button和image组件的基本用法
    其它常用组件button按钮组件功能比HTML中的button按钮丰富通过open-type属性可以调用微信提供的各种功能(客服、转发、获取用户授权、获取用户信息等)image......
  • 数据库在执行全库恢复后,open时报错ORA-01113、ORA-01110 ORA-00312 ORA-01113
    问题描述:数据库在执行全库恢复后,open时报错ORA-01113、ORA-01110ORA-00312ORA-01113系统:Anolis7.9数据库:oracle11.2.0.41、问题描述数据库在执行全库恢复后,open时报错OR......
  • One Bamboo Contest Round #11(Clone from 2022 ICPC Manila)
    马尼拉区域赛题目出得还是不错的,只是感觉大多数参赛队伍的水平不太行,我们这样的队伍居然能苟到铜牌A.AnEasyCalculusProblem签到#include<bits/stdc++.h>#define......
  • 代码随想录——贪心算法
    分发饼干题目简单这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。classSolution{//思路:优先考虑胃口,先喂饱......
  • 最完美WIN11_Pro_22H2.22623.1095软件选装纯净版VIP38.4
    【系统简介】=============================================================1.本次更新母盘来UUP_WIN11_Pro_22H2.22623.1095。进一步优化调整。2.不支持更新,更新后精简版......
  • 新概念第一册111~120单元学习笔记
    Chapterhundredandeleven:ThemostexpensivemodelDialogue标题用到more的用法more/themost+adj.#多音节(>=2)形容词,前加more,most表更多less/theleast+adj.#少......