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

文章介绍了使用栈解决C++编程中的三个问题:检查有效括号字符串,删除字符串中的相邻重复项以及计算逆波兰表达式。通过栈,可以有效地处理括号匹配,消除相邻重复字符以及执行后缀表达式的计算。每个问题都提供了相应的C++代码实现。

20. 有效的括号

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 每个右括号都有一个对应的相同类型的左括号。

题目链接

视频链接

思路:

for循环遍历查找对应括号

看完代码随想录之后的思路:

使用栈,这样可以同时解决数量和顺序的问题

遇到的非法情况无非三种:左边括号多了,右边括号多了,括号不多不少但是不匹配

class Solution {
public:
    bool isValid(string s) {
        if(s.size()%2!=0)return false;
        stack<char> st;
        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('}');
            else if(st.empty()||st.top()!=s[i])return false;
            //右括号多了,括号不多不少却不匹配
            else st.pop();
        }
        return st.empty();//左边括号多了
    }
};

遇到的困难:

else if(st.empty()||st.top()!=s[i])return false;

这一句中,需要西安判断是否为空,否则,如果是空栈却取了top,会报非法错误

收获:

if……else if 的条件集合是可以互相转化的,所以先写执行类型少的集合,最后else写执行类型多的集合

判断栈的top()元素时,一定先判断是否为empty()

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

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

题目链接

视频链接

思路:

看完代码随想录之后的思路:

使用栈,但是需要使用一个字符串来保存pop的结果

class Solution {
public:
    string removeDuplicates(string s) {
        stack<char> st;
        for(int i=0;i<s.size();i++)
        {
            if(st.empty()||st.top()!=s[i])st.push(s[i]);
            else st.pop();
        }
        string result="";
        while(!st.empty())
        {
            result+=st.top();
            st.pop();
        }
        reverse(result.begin(),result.end());
        return result;
    }
};

或者直接将一个字符串当做栈,从backpush进去,这样最后留下来的直接可以输出

class Solution {
public:
    string removeDuplicates(string S) {
        string result;
        for(char s : S) {
            if(result.empty() || result.back() != s) {
                result.push_back(s);
            }
            else {
                result.pop_back();
            }
        }
        return result;
    }
};

收获:

在C++中,用单引号' '定义的是字符(char)类型,用双引号" "定义的是字符串(string)类型。

需要注意的是,如果在单引号中间包含多个字符,编译器会报错。如果单引号中间没有字符,编译器也会报错。

字符串的拼接可以直接使用+=

for(s:S)这种写法,不需要加索引,但是普通的for循环需要加索引

递归的返回也是用栈,但是大项目尽量不要用递归,更容易判断不充分return的条件,非常容易无限递归(或者递归层级过深),造成栈溢出错误(这种问题还不好排查!)

栈的适用类型:特别适合做相邻元素的特殊判断,例如相邻括号匹配,相邻字符消除

150. 逆波兰表达式求值

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

注意:

  • 有效的算符为 '+'、'-'、'*' 和 '/' 。
  • 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
  • 两个整数之间的除法总是 向零截断 。
  • 表达式中不含除零运算。
  • 输入是一个根据逆波兰表示法表示的算术表达式。
  • 答案及所有中间计算结果可以用 32 位 整数表示。

题目链接

视频链接

思路:

看完代码随想录之后的思路:

使用栈的方式,进行后缀表达式的计算

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);
                else if(tokens[i]=="-")st.push(num2-num1);
                else if(tokens[i]=="*")st.push(num2*num1);
                else if(tokens[i]=="/")st.push(num2/num1);
            }
            else st.push(stoll(tokens[i]));
        }
        long long result=st.top();
        st.pop();
        return result;
    }
};

遇到的困难:

vector<string> 类型的数据表示一个字符串数组,每个元素都是一个字符串,而字符串需要使用双引号 " " 表示,而不能使用单引号 ' '。定义如下:std::vector<std::string> words = {"hello", "world"};

后缀表达式,所以是使用后出栈做被算数,先出栈做算数:num2/num1

stoll 是 C++ 中的一个函数,用于将字符串转换为长整型数(long long 类型)。

std::string str = "1234567890";
long long num = std::stoll(str);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值