DAY11|栈与队列PART2

文章讲述了如何利用栈和队列数据结构解决编程中的两个问题:检查有效括号配对和删除字符串中的相邻重复项,以及如何评估逆波兰表达式。作者通过实例展示了如何运用这些技术并分享了思考过程。
摘要由CSDN通过智能技术生成

焦虑了就来写一篇发泄一下。。。不想复习考试。。。

20. 有效的括号

好经典的一道题,感觉经常能在面经中看到

class Solution {
public:
    bool isValid(string s) {
        unordered_map<char,char> myMap;
        stack<char> cache;
        myMap.insert({')','('});
        myMap.insert({'}','{'});
        myMap.insert({']','['});
        int len=s.size();
        for(int i=0;i<len;++i){
            if(myMap.count(s[i])==0){
                cache.push(s[i]);
            }
            else{
                if(cache.empty()) return false;
                char t=cache.top();
                auto it=myMap.find(s[i]);
                if(t==(it->second)){
                    cache.pop();
                }
                else{
                    return false;
                }
            }
        }
        return cache.empty()!=0? true : false;
    }
};

思路很简单,
哈希表里的三组数是为了记录匹配的括号类型。准备一个栈,如果是正括号就先入栈,如果是反括号,就弹出栈顶元素,如果能和反括号类型匹配上,则继续下一轮循环。
循环结束后查看栈是否为空,为空表示正反括号都一一对应上了,否则是有没对应上的正括号仍存在栈中,返回false即可。
取或者弹出栈顶元素的时候记得先看栈是否为空。
好了,下一道

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

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

用栈写的,大体思路:
字符串一个一个入栈,入栈的时候与栈顶元素对比,如果相等就弹出栈顶元素,然后指针也移向下一个字符串中的元素,一次遍历即可完成。
最后从栈中倒出所有元素放到结果字符串的时候,需要把结果字符串reverse一下。
为什么不能用队列(也不是不能用,感觉非常不方便)
队列先进先出,没法弹出上一个刚入队列的元素(可以通过back取到,但没法很方便地去除掉队尾元素)
时间和空间复杂度都是O(N)
(说句题外话,如果这题不是放在队列和栈的模块,我未必能想到用栈来做)

150. 逆波兰表达式求值

class Solution {
public:
    int evalRPN(vector<string>& tokens) { // 注意是string
        stack<int> s;                     // 栈里只放整型数
        int n = tokens.size();
        for (int i = 0; i < n; ++i) {
            char curr;
            if (tokens[i].size() == 1) { // 可能是 数字可能是 运算符
                curr = tokens[i][0];
                if (curr == '+' || curr == '-' || curr == '*' || curr == '/') {
                    int a = s.top();
                    s.pop();
                    int b = s.top();
                    s.pop();
                    int sum;
                    if (curr == '+') {
                        sum = a  + b ;
                        s.push(sum);
                    } else if (curr == '-') {
                        sum = b - a;
                        s.push(sum);
                    } else if (curr == '*') {
                        sum = (a) * (b);
                        s.push(sum);
                    } else {
                        sum = (b) / (a);
                        s.push(sum);
                    }
                } 
                else {
                    s.push(curr-'0');
                }
            }
            else { // 一定是数字
                s.push(convert_to_int(tokens[i]));
            }
        }
        
        int result = s.top() ;
        return result;
    }
    int convert_to_int(string s){
        int n=s.size();
        int count=1;
        int result=0;
        for(int i=n-1;i>=0;--i){
            if(s[i]=='-'){
                result=0-result;
            }
            else{
                int curr=s[i]-'0';
                curr=curr*count;
                count=count*10;
                result+=curr;
            }
        }
        return result;
    }
};

虽然不是一遍写对的但感觉也没涉及什么算法了。。。
我的思路大概是这样:
如果元素是非运算符,就正常入栈。
如果元素是运算符,弹出栈顶的两个元素a,b,进行运算(注意减法和除法的顺序,后弹出来的作被减数或被除数)运算后的结果入栈。
循环结束后取出栈顶元素(理论上这时候栈内应该只有一个元素)

vector里装的是string是一个需要注意的点,string长度为1的时候,可能是个位数,也可能是运算符。
如果不是运算符,直接取出-‘0’转换成整型数入栈即可。
string长度不为1的时候,需要将其转换成int型数入栈(这里我额外写了一个函数)

写完看题解的时候才发现字符串有现成的库函数可以直接将其转换成long long型整数。。。
st.push(stoll(tokens[i]));
好的、、、又学到了一个库函数stoll、、下次记得用

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值