LeetCode 热题 100 - 回溯 - 括号生成 - javascript

题目

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

输入:n = 1
输出:["()"]

解答

图片来源于视频截图https://www.bilibili.com/video/BV1mPimYGE4q?p=54&vd_source=b42b3b4ccc197fbbaf3f1dbdb048417a

图中数字是左右括号剩余数量

算法思路

  1. 初始化:创建一个空数组 ans 来存储所有有效的括号组合。

  2. 深度优先搜索(DFS)

    • str:当前构建的括号字符串

    • left:剩余可用的左括号数量

    • right:剩余可用的右括号数量

  3. 递归过程

    • 边界条件:当字符串长度达到 2n 时,说明得到一个有效组合,将其加入结果数组

    • 添加左括号:只要还有剩余的左括号(left > 0),就可以添加左括号

    • 添加右括号:只有当剩余的右括号比左括号多时(right > left)才能添加右括号(这保证了括号的有效性)

  4. 初始调用:从空字符串开始,初始可用的左右括号数均为 n。


示例解析(n=2)

递归调用过程:

  1. 初始调用 dfs('', 2, 2)

  2. 添加 '(' → dfs('(', 1, 2)

    • 添加 '(' → dfs('((', 0, 2)

      • 只能添加 ')' → dfs('(()', 0, 1)

        • 只能添加 ')' → dfs('(())', 0, 0) → 加入结果

    • 添加 ')' → dfs('()', 1, 1)

      • 添加 '(' → dfs('()(', 0, 1)

        • 添加 ')' → dfs('()()', 0, 0) → 加入结果

      • 不能直接添加 ')'(因为 right == left)

最终结果:['(())', '()()']

var generateParenthesis = function(n) {
    // 存储所有有效括号组合的结果数组
    let ans = [];
    
    /**
     * 深度优先搜索(DFS)递归函数
     * @param {string} str - 当前构建的括号字符串
     * @param {number} left - 剩余可用的左括号数量
     * @param {number} right - 剩余可用的右括号数量
     */
    let dfs = (str, left, right) => {
        // 递归边界条件:当字符串长度达到2n时(即用完所有括号)
        if (str.length === n * 2) {
            ans.push(str); // 将完整组合加入结果数组
            return;
        }
        
        // 只要还有左括号可用,就可以添加左括号
        if (left > 0) {
            // 添加左括号,剩余左括号数量减1
            dfs(str + "(", left - 1, right);
        }
        
        // 只有当剩余的右括号比左括号多时,才能添加右括号
        // 这保证了括号的有效性(不会出现无效的右括号)
        if (right > left) {
            // 添加右括号,剩余右括号数量减1
            dfs(str + ")", left, right - 1);
        }
    };
    
    // 从空字符串开始,初始可用的左右括号数均为n
    dfs('', n, n);
    
    // 返回所有有效的括号组合
    return ans;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值