zoukankan      html  css  js  c++  java
  • 22. 括号生成【中等】

    leetcode:https://leetcode-cn.com/problems/generate-parentheses/

    方法一:

    动态规划

    n:代表有n对括号

    ans[i]:代表一共 i 对括号形成的所有组合

    我们要求的是ans[n]

    我们知道对于第n对括号是由一个左括号和一个右括号组成,而且无论多少对括号组成的排列的最左边一定是左括号

    然后对于n对括号形成的组合中,剩下n-1对括号要么是在第n对括号中间,要么在第n对括号右边

    所以假设我们知道1到 n - 1 括号形成的所有组合ans[1]到ans[n - 1],则对于n对括号组成的所有组合,无非就是

    ( + ans[q] + ) + ans[r]

    我们知道ans[1] = ['()']

    所以ans[2]的所有组合就是

    ( + ans[0] + ) + ans[1]

    ( + ans[1] + ) + ans[0]

    这样就可以得到ans[1]和ans[2],利用之前计算的结果,然后依次递推可以计算出ans[3]、ans[4]。。。ans[n]

    /**
     * @param {number} n
     * @return {string[]}
     */
    var generateParenthesis = function(n) {
        // 第1组组合只有一种
        let ans = [[],['()']];
        // 还需要在原来基础上还需要增加i组括号
        for (let i = 2; i <= n; i++) {
            ans[i] = [];
            let temp = [];
            // 遍历组合ans[j]和 ans[i - j]形成的所有组合
            for (let j = 0; j < i; j++) {
                const qArr = ans[j];
                const rArr = ans[i - j - 1];
                // 右边没有
                if (qArr.length === 0) {
                    for (let r = 0, rLen = rArr.length; r < rLen; r++) {
                        temp.push('()' + rArr[r]);
                    }
                    continue;
                }
                // 中间没有
                if (rArr.length === 0) {
                    for (let q = 0,qLen = qArr.length; q < qLen; q++) {
                        temp.push('(' + qArr[q] + ')')
                    }
                    continue;
                }
                // 中间和右边都有
                for (let q = 0,qLen = qArr.length; q < qLen; q++) {
                    for (let r = 0, rLen = rArr.length; r < rLen; r++) {
                        temp.push('(' + qArr[q] + ')' + rArr[r]);
                    }
                }
            }
            ans[i] = temp;
            console.log(`ans[${i}]`, ans[i])
        }  
        return ans[n];
    };

    方法二:

    深搜dfs + 剪枝

    其实就是插入n次括号,每次有两种选择,左括号或者右括号,可以当做一个二叉树

    边界:左右括都已经插入n个了,即形成要求的一组组合

    不符合条件的:插入左括号或者右括号超过n个,或者右括号数量超过左括号,对于二叉树遍历过程中遇到这样的不再继续遍历,也就是【剪枝】

    /**
     * @param {number} n
     * @return {string[]}
     */
    var generateParenthesis = function(n) {
        let arr = [];
        // 二叉树深搜    
        const dfs = function (arr, str, l, r, n) {
            // 不符合组合条件的不再递归【剪枝】    
            if (l > n || r > n || r > l) return;
            if (l === n && r === n) {
                arr.push(str);
                return;
            }
            // 加左括号
            dfs(arr, str + '(', l + 1, r, n);
            // 加右括号
            dfs(arr, str + ')', l, r + 1, n);
        }
        dfs(arr, '', 0, 0, n);
        return arr;
    };

    -----smile

  • 相关阅读:
    kubernetes
    dubbo
    前端控件+资源
    Gossip
    问题解决1
    react
    impala
    storm+Calcite
    ASP.NET页面传值与跳转
    经典FormsAuthenticationTicket 分析
  • 原文地址:https://www.cnblogs.com/Walker-lyl/p/14593133.html
Copyright © 2011-2022 走看看