美文网首页
32、最长有效括号 | 算法(leetode,附思维导图 + 全

32、最长有效括号 | 算法(leetode,附思维导图 + 全

作者: 码农三少 | 来源:发表于2021-11-27 17:43 被阅读0次

    零 标题:算法(leetode,附思维导图 + 全部解法)300题之(32)最长有效括号

    一 题目描述

    题目描述

    二 解法总览(思维导图)

    思维导图

    三 全部解法

    1 方案1

    1)代码:

    // 方案1 “滑动窗口法”。
    // 通过:229 / 231,超时!
    // 例子:太长,暂不罗列。
    
    // 思路:
    // 1)初始化状态。
    // 2)核心:窗口大小固定为 tempL(范围:[l, 0] ) ,不断穷举所有的可能情况、然后做处理
    // tempL:当前窗口大小, left、right 分别为当前窗口的左右边。
    // 3)返回结果
    var longestValidParentheses = function(s) {
        // 判断当前子串 tempS 是否为 有效括号
        const isValidParentheses = (tempS = '') => {
            const l = tempS.length;
            let stack = [];
    
            for (let i = 0; i < l; i++) {
                if (tempS[i] === '(') {
                    stack.push('(');
                }
                else {
                    const tempChar = stack.pop();
                    if (tempChar !== '(') {
                        return false;
                    }
                }
            }
    
            return stack.length === 0;
        };
    
        // 1)初始化状态。
        const l = s.length;
    
        // 2)核心:窗口大小固定为 tempL(范围:[l, 0] ) ,不断穷举所有的可能情况、然后做处理
        // tempL:当前窗口大小, left、right 分别为当前窗口的左右边。
        for (let tempL = l; tempL > 0; tempL--) {
            // 优化:长度为奇数,肯定不是!
            if (tempL % 2 === 1) {
                continue;
            }
    
            for (let left = 0; left < (l - tempL + 1); left++) {
                const right = (left + tempL - 1);
                // 优化:最左、最右的字符一定分别是 '('、')' !
                if (s[left] !== '(' || s[right] !== ')') {
                    continue;
                }
                else {
                    const tempS = s.slice(left, right + 1);
                    if (isValidParentheses(tempS)) {
                        // 3)返回结果
                        return tempL;
                    }
                }
            }
        }
    
        // 3.2)返回结果
        return 0;
    };
    

    2 方案2

    1)代码:

    // 方案2 “动态规划”。
    
    // 思路:
    // 1)我们用 dp[i] 表示以 i 结尾的最长有效括号
    // 2.1)若 s[i] 为 ( ,则 dp[i] 必然等于 0,因为不可能组成有效的括号
    // 2.2)若 s[i] 为 ),
    // 2.2.1)且当 s[i-1] 为 (,则 dp[i] = dp[i-2] + 2;
    // 2.2.2)且当 s[i-1] 为 ) && s[i-dp[i-1] - 1] 为 (,则 dp[i] = dp[i-1] + 2 + dp[i-dp[i-1]-2] 。
    // 3)返回结果 resLength 
    // 参考:
    // 1)https://leetcode-cn.com/problems/longest-valid-parentheses/solution/dong-tai-gui-hua-si-lu-xiang-jie-c-by-zhanganan042/
    var longestValidParentheses = function(s) {
        // 1)状态初始化
        const l = s.length;
        let dp = Array(l).fill(0),
            resLength = 0;
    
        // 2)核心:
        // 1)我们用 dp[i] 表示以 i 结尾的最长有效括号
        // 2.1)若 s[i] 为 ( ,则 dp[i] 必然等于 0,因为不可能组成有效的括号
        // 2.2)若 s[i] 为 ),
        // 2.2.1)且当 s[i-1] 为 (,则 dp[i] = dp[i-2] + 2;
        // 2.2.2)且当 s[i-1] 为 ) && s[i-dp[i-1] - 1] 为 (,则 dp[i] = dp[i-1] + 2 + dp[i-dp[i-1]-2] 。
        for (let i = 0; i < l; i++) {
            if (i > 0 && s[i] === ')') {
                if (s[i - 1] === '(') {
                    dp[i] = ((i - 2 >= 0) ? dp[i - 2] + 2 : 2);
                }
                else if (s[i - 1] === ')' && (i - dp[i - 1] - 1 >= 0) && (s[i- dp[i - 1] - 1] === '(')) {
                    dp[i] = dp[i - 1] + 2 + (i - dp[i - 1] - 2 >= 0 ? dp[i - dp[i - 1] - 2] : 0);
                }
            }
            resLength = Math.max(resLength, dp[i]);
        }
    
        // 3)返回结果 resLength 
        return resLength;
    }
    

    相关文章

      网友评论

          本文标题:32、最长有效括号 | 算法(leetode,附思维导图 + 全

          本文链接:https://www.haomeiwen.com/subject/ogkqxrtx.html