[算法基础] 栈相关-最长有效的括号

题目

给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。

示例 1:

输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"

示例 2:

输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"

解题思路

我们可以通过栈,在遍历给定字符串的过程中,判断到目前位置的子串的有效性。然后更新最长的有效长度。
具体做法

  • 对于遇到的每一个(,我们将他的下标放入栈中。
  • 当扫描到),则弹出一个次,并记录有效长度为:当前索引 - 出栈索引 + 1,更新最大值。

但是示例2中我们可见,一开始我们扫描到的就是),此时栈为空,无法弹出。并且如果在扫描的过程中,栈为空,我们再次遇到),也不能继续向下进行。因此我们需要设立一个参照物,确保栈在整个扫描的过程中不为空,可计算。

  • 对于开始扫描时,设置栈中初始元素为 -1,如果顺利扫描如 (())这样的字符串,则有效长度为3-(-1) = 4 没有任何影响,此时-1为栈顶值。
  • 对于开始扫描时,设置栈中初始元素为 -1,如果描如 )())这样的字符串,遇到)直接-1出栈,此时栈为空,再次入栈的如果为(的索引即1,则再次遇到)出栈时,计算会出错,长度为2-1 = 1。所以我们同样需要一个参照元素用以计算有效长度。可以选择栈为空时候遇到的右括号的索引作为参照元素,恰巧比下一个入栈(的索引小1。便于统一计算。
  • 遇到连续的),也会不断弹出上一个参照元素。弹出机制可以保持栈中的参照元素时最接近下一个(的元素。
/**
 * @param {string} s
 * @return {number}
 */
var longestValidParentheses = function(s) {
    var maxLen = 0;
    const stack = [-1];
    for (let i = 0; i < s.length; i++) {
        const c = s[i];
        if (c == '(') {     // 左括号的索引入栈 
            stack.push(i);
            continue;       // 跳过,考察下一个符号
        }
        stack.pop();        // 遇到右括号,栈顶出栈
        if (stack.length == 0) {    // 栈变空了,右括号匹配不到人了
            stack.push(i);          // 说明它要充当“参照物”了
        } else {                    // 右括号找到匹配,计算有效的连续长度,挑战最大
            maxLen = Math.max(maxLen, i - stack[stack.length - 1]);
        }
    }
    return maxLen;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值