leetcode每日一题(2020-07-04):32. 最长有效括号

题目描述:
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

注意:我连续想错了两次题目意思,可以嵌套,只要左右匹配就好

今日学习:
1.察觉到异常的时候要把它揪出来想,不要忽视它

题解:
1.维护一个栈,但是栈中存的并不是左括号,而是左括号的索引,这样就可以每次都计算出子串的长度了
2.左右遍历s,计算左右括号数量是否匹配
3.这道题动规真难,没想明白,我放弃了

// 错误题解:维护一个'('栈,但是想法有一些问题,有些情况没考虑进去
var longestValidParentheses = function(s) {
    let res = 0, count = 0, later = 0
    let stack = []
    for(i = 0; i < s.length; i++) {
        if(s[i] == '(') {
            stack.push(s[i])
        }else {
            if(stack.length == 0) {
                res = Math.max(res, count)
                count = 0
            }else {
                stack.pop()
                count += 2
            }
        }
    }
    res = Math.max(res, count)
    return res
}
// 还是维护栈,但是栈存的是索引而不是括号
var longestValidParentheses = function(s) {
    let start = s.indexOf('(')
    let end = s.lastIndexOf(')')
    if(start == -1 || end == -1 || start > end) return 0
    s = s.slice(start, end + 1)
    // 前四行可以处理掉一些极端情况,有没有都可以
    let maxLen = 0;
    // 预存索引-1,方便计算长度,也是作为新的开始
    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;
};
// 左右算括号数量的思想
var longestValidParentheses = function(s) {
    let start = s.indexOf('(')
    let end = s.lastIndexOf(')')
    if(start == -1 || end == -1 || start > end) return 0
    s = s.slice(start, end + 1)
    // 前四行可以处理掉一些极端情况,有没有都可以
    let left = right = 0, maxLen = 0
    // 从左到右遍历
    for(let i = 0; i < s.length; i++) {
        //遇到左括号或者右括号,对应数量+1
        if(s.charAt(i) == '(') {
            left++
        }else {
            right++
        }
        // 如果数量相等,说明符合子串要求,计算当前长度
        // 如果右大于左,没有继续计算长度的必要,left和right归零
        if(left == right) {
            maxLen = Math.max(maxLen, 2 * left)
        }else if(right > left) {
            left = right = 0
        }
    }
    // 从右往左遍历,思路一致
    left = right = 0
    for(let i = s.length - 1; i >= 0; i--) {
        if(s.charAt(i) == ')') {
            right++
        }else {
            left++
        }
        if(left == right) {
            maxLen = Math.max(maxLen, 2 * left)
        }else if(left > right) {
            left = right = 0
        }
    }
    return maxLen
}
原文地址:https://www.cnblogs.com/autumn-starrysky/p/13234183.html