Loading

括号生成

1.问题描述

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

示例:

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

2.求解

递归

  • 看到这种输出所有可能的组合的情况,首先想dfs(深度优先遍历)
  • 对于每一层的递归,在左括号剩余的情况下,优先拼接左括号,在右括号数量小于左括号的情况下,才可以使用右括号
代码如下
/*
执行用时:1 ms, 在所有 Java 提交中击败了96.65% 的用户
内存消耗:39 MB, 在所有 Java 提交中击败了41.80% 的用户
* */
List<String> list = new ArrayList<>();
public List<String> generateParenthesis(int n) {
    dfs("", n, n);
    return list;
}

private void dfs(String str, int left, int right) {
    if (left == 0 && right == 0) {
        list.add(str);
        return;
    }
    if (left > 0) {
        dfs(str + "(", left-1, right);
    }
    if (right > left) {
        dfs(str + ")", left, right-1);
    }
}

动态规划

  • 使用dp[i]表示括号数为i时,生成的有效括号组合
  • 则递推公式为dp[i] = "(" + dp[m] + ")" + dp[k],其中m+k+1=i
  • i = 0时为空,dp[0]= ""
  • 于是我们就可以遍历所有小于i的m来获取所有情况
代码如下
/*
* 执行用时:10 ms, 在所有 Java 提交中击败了10.78% 的用户
* 内存消耗:39.3 MB, 在所有 Java 提交中击败了10.64% 的用户
* */
public List<String> generateParenthesis(int n) {
    List[] dp = new List[n + 1];
    List<String> dp0 = new ArrayList<>();
    dp0.add("");
    dp[0] = dp0;
    for (int i = 1; i <= n; i++) {
        List<String> cur = new ArrayList<>();
        for (int m = 0; m < i; m++) {
            int k = i - 1 - m;
            List<String> str1 = dp[m];
            List<String> str2 = dp[k];
            for(String s1 : str1){
                for(String s2 : str2){
                    cur.add("(" + s1 + ")" + s2);
                }
            }
        }
        dp[i] = cur;
    }
    return dp[n];
}
posted @ 2020-10-10 16:37  水纸杯  阅读(115)  评论(0)    收藏  举报