leetcode678有效的括号字符串

678. 有效的括号字符串

上过数据结构课的最直观的印象,括号匹配用栈来存储

这个题目的变化就是增加了一个*,可以代替左右括号或者视为空,依然可以用栈来解题,设置左括号和星号的栈,保存二者在字符串s中的位置,当遇到右括号时,优先pop左括号栈,左括号栈为空再pop星号栈,如果都空则false,最后通过左括号栈和星号栈中存的位置来判断星号和左括号是否可以匹配

class Solution {
public:
    bool checkValidString(string s) {
        stack<int> leftStack, starStack;
        for (int i = 0; i < s.size(); ++i) {
            if (s[i] == '(') {
                leftStack.push(i);
            } else if (s[i] == '*') {
                starStack.push(i);
            } else if (s[i] == ')') {
                if (!leftStack.empty()) {
                    leftStack.pop();
                } else if (!starStack.empty()) {
                    starStack.pop();
                } else {
                    return false;
                }
            }
        }
        while (!leftStack.empty() && !starStack.empty()) {
            if (leftStack.top() > starStack.top())return false;
            leftStack.pop();
            starStack.pop();
        }
        return leftStack.empty();
    }
};

这种做法的时间复杂度达到了O(n)但是由于使用了额外的数据结构,空间复杂度也达到了O(n)

但是实际上并不需要维护左括号和星号的位置,只需要保证在左括号和右括号满足条件后左括号和星号也满足就可以了

遇到左括号,左括号数量加一

遇到右括号,左括号数量减一

遇到星号,则可能作为左括号也可能作为右括号,也可能忽略,也就是说左括号的数量加一减一或者不变,那么我们可以维护左括号的数量的范围leftMax和leftMin

在遍历s的过程中,如果左括号的最大数量比零要小,那么一定无法匹配,直接false

遍历结束,如果左括号的最小数量为零,说明可以匹配

class Solution {
public:
    bool checkValidString(string s) {
        int leftMax = 0, leftMin = 0;
        for (char i : s) {
            if (i == '(') {
                leftMax++;
                leftMin++;
            } else if (i == '*') {
                leftMax++;
                leftMin = max(0, leftMin - 1);
            } else if (i == ')') {
                leftMax--;
                leftMin = max(0, leftMin - 1);
                if (leftMax < 0) { // 
                    return false;
                }
            }
        }
        return leftMin == 0;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值