《六月集训》(第十四天)——栈

前言

        欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
        今天是六月集训第十四天:🔥🔥
在这里插入图片描述

一、练习题目

        剑指 Offer 31. 栈的压入、弹出序列
        946. 验证栈序列
        856. 括号的分数
        1190. 反转每对括号间的子串

二、算法思路

  • 1、剑指 Offer 31. 栈的压入、弹出序列:这是一道很经典的栈模拟题,考数据结构的时候经常会手推。这题设计一个辅助栈来模拟一下是否能得到弹出的结果。🔥🔥

  • 2、946. 验证栈序列:同上。🔥🔥

  • 3、856. 括号的分数:括号匹配的类型可以用栈,递归,dfs等。这里我用栈来模拟一下。画个图🔥🔥
    在这里插入图片描述

  • 4、1190. 反转每对括号间的子串:简单题,利用栈来找括号,然后将括号内的字符串翻转即可。🔥

三、源码剖析

// 剑指 Offer 31. 栈的压入、弹出序列
// 946. 验证栈序列
class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        stack<int> stk; //(1)
        int j = 0;
        for(int i = 0; i < pushed.size(); ++i) {
            stk.push(pushed[i]); //(2)
            while(!stk.empty() && stk.top() == popped[j]) { //(3)
                stk.pop();
                j++;
            }
        }
        return stk.empty(); //(4)
    }
};
  • 1、建立辅助栈;
  • 2、遍历所有的pushed元素,模拟入栈的情况;
  • 3、如果辅助栈的栈顶元素与popped中元素相等,模拟出栈操作;
  • 4、判断辅助栈的状态。为空,返回true;不为空,返回false,因为如果能弹出的辅助栈一定被清空。
// 856. 括号的分数
class Solution {
public:
    int scoreOfParentheses(string s) {
        stack<int> stk;
        for(char c: s) {
            if(c == '(') { //(1)
                stk.push(0);
            } else {
                if(stk.top() == 0) { //(2)
                    stk.pop();
                    stk.push(1);
                } else { //(3)
                    int cnt = 0;
                    while (stk.top())
                    {
                        cnt += stk.top();
                        stk.pop();
                    }
                    stk.pop();
                    stk.push(cnt * 2);
                }
            }
        }
        int ans = 0;
        while (!stk.empty()) //(4)
        {
            ans += stk.top();
            stk.pop();
        }
        return ans;
    }
};
  • 1、字符其实有指定的ASCII码值,我们直接用固定的数字模拟,碰到左括号用0代替;
  • 2、碰到右括号了,同时栈顶是0表示左括号,根据题意()是要转换成1分的,弹出左括号,压入1;
  • 3、碰到右括号,但是栈顶不是0,说明是(ABC……)这么个情况,我们需要用一个计数器cnt累加他们,根据题意累加完后cnt*2,同时弹出左括号,压入cnt;
  • 4、最后栈内只有分数了,就是累加的情况。
// 1190. 反转每对括号间的子串
class Solution {
public:
    string reverseParentheses(string s) {
        stack<int> stk;
        for(int i = 0; i < s.length(); ++i) {
            if(s[i] == '(') {
                stk.push(i); //(1)
            } else {
                if(s[i] == ')') { //(2)
                    int l = stk.top() + 1;
                    int r = i - 1;
                    stk.pop();
                    while(l <= r) {
                        char tmp = s[l];
                        s[l++] = s[r];
                        s[r--] = tmp;
                    }
                }
            }
        }
        string ans;
        for(auto c : s) {
            if(c != '(' && c != ')') { //(3)
                ans += c;
            }
        }
        return ans;
    }
};
  • 1、左括号的话吧下标入栈;
  • 2、碰到右括号,栈顶肯定是一个左括号,如果中间有字符串那么从栈顶加1的位置开始就是字符串的头,同时当前位置减1肯定是字符串的尾,利用这双指针的移动进行字符的翻转;
  • 3、最后把字符取出来就是答案了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值