算法训练营笔记第十一天|20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

目录

20. 有效的括号

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

150. 逆波兰表达式求值

总结


20. 有效的括号

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

笔记:

1.先确定一共有三种不对应的括号排列方式

        左括号多了         (({})

        右括号多了              {})

        左右括号不匹配    {(})

2.左括号多了:从左面开始遍历数据元素,遍历到是左面的括号,那就在栈里面放一个同样的右方向括号,当遍历到相同的右方向括号,删除掉这个元素,若左括号多了,那么在遍历完所有元素之后栈里面还会剩余括号

3.左右括号不匹配:遍历的元素和栈里面的括号不匹配

4.右括号多了:遍历元素时,栈里面没有相应的元素了

5.elseif(stack != NULL && stack.top() != s[i])一定要注意先判断栈是不是空的

一开始的错误代码:

class Solution {
public:
    bool isValid(string s) {
        //创建一个数据类型是int或者char的栈,如果是int,那么符号会用ASCII编码,还是可行的
        stack <int> st;
        int size = s.size();

        //如果s的数量都不是双数,那肯定有不成对的符号,直接false
        if(size%2 == 1){
            return false;
        }

        //遍历这个字符串
        for(int i = 0; i < size; i++){
            if(s[i] == "("){
                st.push(")");
            }else if(s[i] == "{"){
                st.push("}");
            }else if(s[i] == "["){
                st.push("]");
            }else if(!s.empty() && s[i]!= st.top()){
                return false;
            }else{
                st.pop();
            }
        }

        //遍历所有元素之后,若stack里还有元素,那么说明左括号多了
        if(!st.empty()){
            return false;
        }else{
            return true;
        }
    }
};

debug记录:

  •  s是一个字符串string,私以为可以把它看做是一个char组成的表格,所以for循环去遍历s的时候,里面的每一个元素的数据类型应该是char或者是int,与单引号' '比较

  • 这里不是&&,而是||,不论是这两个的哪一种情况,都是错误的,栈是空的,说明右方向的括号多了,元素和栈里的数对不上说明左右括号不搭
  • 还有我明明懂不能栈是空的,也就是判断语句是 st.empty() 是false,我还是写反了还写成了string s

最后正确的结果:

class Solution {
public:
    bool isValid(string s) {
        //创建一个数据类型是int或者char的栈,如果是int,那么符号会用ASCII编码,还是可行的
        stack <int> st;
        int size = s.size();

        //如果s的数量都不是双数,那肯定有不成对的符号,直接false
        if(size % 2 == 1)   return false;
        
        //遍历这个字符串
        for(int i = 0; i < size; i++){
            if(s[i] == '('){
                st.push(')');
            }else if(s[i] == '{'){
                st.push('}');
            }else if(s[i] == '['){
                st.push(']');
            }else if(st.empty() || s[i]!= st.top()){
                return false;
            }else{
                st.pop();
            }
        }

        //遍历所有元素之后,若stack里还有元素,那么说明左括号多了
        if(!st.empty()){
            return false;
        }else{
            return true;
        }
    }
};


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

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

看完视频的笔记:

  • 利用for循环遍历字符串的元素,然后放入stack中,每放入一个就和stack.top()比较,也就是上一个放进去的元素, 如果相等,那就把栈顶的元素弹出,且继续向后遍历
  • stack可以不用非得是栈,也可以是一个字符串
  • 对于字符串来说,使用的是push_back(),pop_back(),back()
  • 使用了栈的思想,以后删除重复项就可以这么思考

根据视频中的思路写的代码一遍过,嘿嘿:)

class Solution {
public:
    string removeDuplicates(string s) {
        //创建一个模拟栈的字符串s
        string result;
        int size = s.size();

        for(int i = 0; i < size; i++){
            if(result.empty() || s[i] != result.back()){
                result.push_back(s[i]);
            }else{
                result.pop_back();
            }
        }
        return result;
    }
};


150. 逆波兰表达式求值

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

看完视频之后的笔记:

还是借用栈的思想,用for循环遍历整体数组元素,把不是符号的数字入栈,当遍历到符号时,num1=stack.top(),stack.pop(); num1=stack.top(),stack.pop();

之后再根据相应的符号去做相应的运算,把运算结果再重新放入栈中

接着进行元素的遍历,直到遍历结束

把栈里面唯一的一个值赋值给result,return result,再释放这块内存

自己写的代码:

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        //创建栈用来临时存放结果和数据
        stack<int> s;
        int size = tokens.size();
        int num1;
        int num2;
        int result;
        int r;

        for(int i = 0; i < size; i++){
            if(tokens[i] == + || tokens[i] == - || tokens[i] == * || tokens[i] == /){
                num1 = stack.top();
                stack.pop();
                num2 = stack.top();
                stack.pop();
                if(tokens[i] == + ){
                    result = num1 + num2;
                }else if(tokens[i] == - ){
                    result = num2 - num1;
                }else if(tokens[i] == * ){
                    result = num2 * num1;
                }else{
                    result = num2 / num1;
                }
                stack.push(result);
            }else{
                stack.push(tokens[i]);
            }
        }
        r = stack.top();
        stack.pop();
        return r;
        
    }
};

debug记录: 

 debug:

1.Line 13: Char 31: error: expected expression if(tokens[i] == + || tokens[i] == - || tokens[i] == * || tokens[i] == /){

tokens这个vector里面存放的是string数据类型的数据,所以应该是 == “+”,注意是双引号

2.Line 14: Char 24: error: use of class template 'stack' requires template arguments
                num1 = stack.top();

 设置的栈明明是s,下面我就写成stack了
 

3.Line 29: Char 19: error: no matching member function for call to 'push'
                s.push(tokens[i]);

s中的元素是int,但是tokens里面存放的是string,所以需要进行强制转换

stoi(); 整数型

stoll(); long long型

stof(); 浮点型

成功debug的代码,嘿嘿

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        //创建栈用来临时存放结果和数据
        stack<int> s;
        int size = tokens.size();
        int num1;
        int num2;
        int result;
        int r;

        for(int i = 0; i < size; i++){
            if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){
                num1 = s.top();
                s.pop();
                num2 = s.top();
                s.pop();
                if(tokens[i] == "+" ){
                    result = num1 + num2;
                }else if(tokens[i] == "-" ){
                    result = num2 - num1;
                }else if(tokens[i] == "*" ){
                    result = num2 * num1;
                }else{
                    result = num2 / num1;
                }
                s.push(result);
            }else{
                s.push(stoi(tokens[i]));
            }
        }
        r = s.top();
        s.pop();
        return r;
        
    }
};

老师在网站上写的代码是 long long,应该是因为某段时间力扣更改了测试用例的大小,但是我只使用了int,也是可以正常运行的

总结

在更多的地方上应用了栈的模型,方便了运算,以后也可以在相似的地方上进行这样的思考。而且感觉学习越来越顺了,学习是有用的。一般来说看完视频就可以大致敲出来代码,然后自己慢慢debug,实在不行就去看老师的标准答案

用时:3h 中间还和同学闲聊了一会,真实时间应该小于3h

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值