代码随想录打卡第十一天 | 栈与队列 leetcode20&1047&150(补周六)

目录

20 - 有效的括号

思路:使用栈stack

提交代码

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

思路:暴力破解(双指针)

提交代码

150 - 逆波兰表达式求值

思路:模块化思维,每次只处理一个运算

提交代码


 

20 - 有效的括号

思路:使用栈stack

1、如果是前括号'{' '[' '(',压入栈stk;

2、如果是后括号'}' ']' ')', 和stk的栈顶元素匹配:

        1>匹配, stk栈顶元素删除;

        2>不匹配,return false;

3、遍历完成后,stk为空说明括号全部有效;

提交代码

class Solution {
public:
    bool isValid(string s) {
        if(s.size()%2 > 0)  return false;
        stack<char> stk;
        for(char c : s){
            if(c == '(' || c == '[' || c == '{'){
                stk.push(c);
            }
            else if(c == ')' || c ==']' || c == '}'){
                if(!stk.empty()){
                    char stop = stk.top();
                    stk.pop();
                    if((c == ')' && stop == '(') ||
                        (c == ']' && stop == '[')||
                        (c == '}' && stop == '{'))
                    {
                        continue;
                    }
                }
                return false;
            }
        }
        
        if(stk.size() > 0)  return false;
        return true;
    }
};

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

输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

思路:暴力破解(双指针)

1、如果s.size() < = 1, 直接返回s;

2、双指针l和r,分别为0,1;

3、对比s[l]和s[r]是否相等:

        1>相等,删除s[r]和s[l];(先删除r,再删除l,因为先删除l之后r就左移到原来的l的位置了,此时再删除s[r],r指向的已经不是原来的元素

        2>不相等,l和r后移;

提交代码

class Solution {
public:
    string removeDuplicates(string s) {
        if(s.size() <= 1){
            return s;
        }
        int l = 0; int r = 1;
        while(r < s.size()){
            if(s[l] == s[r]){
                s.erase(r,1);
                s.erase(l,1);
                if(l > 0){
                    l = l - 1;      //删除之后l和r前移一位,判断删除元素之后是否产生新的相邻重复项
                    r = l + 1;
                }

            }
            else{
                ++l;
                ++r;
            }
        }
        return (s);
    }
};

150 - 逆波兰表达式求值

输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
输出:22
解释:该算式转化为常见的中缀算术表达式为:
  ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22

思路:模块化思维,每次只处理一个运算

举例:

输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]

输出:22

解释:该算式转化为常见的中缀算术表达式为: ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 = ((10 * (6 / (12 * -11))) + 17) + 5 = ((10 * (6 / -132)) + 17) + 5 = ((10 * 0) + 17) + 5 = (0 + 17) + 5 = 17 + 5 = 22

 

思路:

1、查找运算符"+" "-" "*" "/",并运算:

        1>计算s[i - 2] <运算符> s[i - 1]的值并保存在原来的i-2位置,i-1和i删除,即使用s[i-2]<运算符>s[i-1]的结果替换原来的s[i-2]s[i-1]s[i]这三个元素,并将i指针移动到i-2,因为用一个元素替换了原来的三个元素;举例:

                i= 4时,s[i] = +,则 newElement = s[i - 2] + s[i - 1];

                                                s[i - 2] = newElement(转成字符串);

                                                删除s[i], 删除s[i - 1];

                                                i = i - 2;

                新的字符串数组为:{"10","6","12","-11","*","/","*","17","+","5","+"},此时i = 2指向12,继续往下遍历,下一次:

                用12 * -11 = -132替换"12" " -11" "*"得到{"10","6","-132","/","*","17","+","5","+"}

                下一次:

                6 / -132 = 0 替换得:{"10","0","*","17","+","5","+"}

                下一次:

                10 * 0 = 0 替换的:{"0","17","+","5","+"}

                下一次:

                0 + 17 = 17替换得:{"17","5","+"}

                下一次:

                15 + 5 = 22替换得:{"22"}, 22即返回值;

        

提交代码

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        int ret = 0;
        for(int i = 0; i < tokens.size(); ++i){
            if(tokens[i] == "+"){
                int newElement = stoi(tokens[i - 2]) + stoi(tokens[i- 1]);
                tokens[i - 2] = to_string(newElement);
                tokens.erase(tokens.begin() + i);
                tokens.erase(tokens.begin() + i - 1);
                i = i - 2;
            }
            else if(tokens[i] == "-"){
                int newElement = stoi(tokens[i - 2]) - stoi(tokens[i- 1]);
                tokens[i - 2] = to_string(newElement);
                tokens.erase(tokens.begin() + i);
                tokens.erase(tokens.begin() + i - 1);
                i = i - 2;
            }
            else if(tokens[i] == "*"){
                int newElement = stoi(tokens[i - 2]) * stoi(tokens[i- 1]);
                tokens[i - 2] = to_string(newElement);
                tokens.erase(tokens.begin() + i);
                tokens.erase(tokens.begin() + i - 1);
                i = i - 2;
            }
            else if(tokens[i] == "/"){
                int newElement = stoi(tokens[i - 2]) / stoi(tokens[i- 1]);
                tokens[i - 2] = to_string(newElement);
                tokens.erase(tokens.begin() + i);
                tokens.erase(tokens.begin() + i - 1);
                i = i - 2;
            }
        }
        ret = stoi(tokens[0]);
        return ret;
    }

    void test(){
        vector<string> vec = {"10","6","9","3","+","-11","*","/","*","17","+","5","+"};
        evalRPN(vec);
    }
};

  • 30
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铁中棠ang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值