[LeetCode] 22. 括号生成(回溯/DP)

题目

给出?n?代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

例如,给出?n = 3,生成结果为:

[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/generate-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

方法一 回溯

  • 回溯法使用递归,并在递归过程中考虑剪枝。此外,递归要考虑终止条件,考虑传的参数,参数可以包括结果的集合,一直要用的变的量,随着递归层数不同变化的计数量,临时的作为最终结果的str。
  • 此题目中,从长度为0到长度为2n递归生成一组有效括号组合,满足条件的下一层递归分支才进入(即进行了剪枝):当当前左括号数量<n时,可以加一个左括号;当当前右括号数量小于左括号数量时,可以加一个右括号。这样保证所有生成的括号都是有效的。

方法二 DP

  • 大概递归思想:dp[n]=‘(‘+dp[i]+‘)‘+dp[n-1-i] ,n 从0到用户输入的N,对于计算dp[n]遍历所有可能的i,,其中dp[n]表示长度为2*n的所有有效串。
  • 存储方法也很有意思,用List<List> ans,最终用ans.get(n)获得长度为2*n的所有有效括号组合。
  • 方法一二的时间复杂度相同,都只遍历了有效的分支,且没有重复。?

代码

代码一 回溯

class Solution {
    public static List<String> generateParenthesis(int n) {
        List<String> parenthesis = new ArrayList<>();
        traceBack("", 0, 0, n, parenthesis);
        return parenthesis;
    }

    private static void traceBack(String str, int left, int right, int n,
            List<String> parenthesis) {
        if (str.length() == 2 * n) {
            parenthesis.add(new String(str));
            return;
        }
        if (left < n) {
            traceBack(str + '(', left + 1, right, n, parenthesis);
        }
        if (right < left) {
            traceBack(str + ')', left, right + 1, n, parenthesis);
        }
    }
}

代码二 DP

class Solution {
   public List<String> generateParenthesis(int n) {
        List<List<String>> parenthesis = new ArrayList<>();// 所有长度<=2n的括号组合

        // 将长度为0的括号组合,放入parenthesis
        ArrayList<String> list = new ArrayList<>();
        list.add("");
        parenthesis.add(list);

        // 由nn为1至n一层层算2*nn长度的括号组合,放入parenthesis
        for (int nn = 1; nn <= n; ++nn) {
            List<String> parenthesisTemp = new ArrayList<>();
            for (int leftLen = 0; leftLen <= nn - 1; ++leftLen) {
                for (String leftStr : parenthesis.get(leftLen)) {
                    for (String rightStr : parenthesis.get(nn - 1 - leftLen)) {
                        parenthesisTemp.add(new String('(' + leftStr + ')' + rightStr));
                    }
                }
            }
            parenthesis.add(parenthesisTemp);
        }

        return parenthesis.get(n);
    }
}

原文地址:https://www.cnblogs.com/coding-gaga/p/12070496.html

时间: 2024-10-08 19:25:34

[LeetCode] 22. 括号生成(回溯/DP)的相关文章

[leetcode] 22. 括号生成

22. 括号生成 谨慎后,1A的概率貌似高了些 算是20题的升级版吧, 利用递归来拼成string,然后通过20. 有效的括号该题的代码来判断生成的string合不合法 看代码吧 class Solution { public List<String> generateParenthesis(int n) { List<String> ans = new ArrayList<>(); dfs(ans, "", n, n); return ans; }

LeetCode 22. 括号生成(Generate Parentheses)

题目描述 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n =3,生成结果为: [ "((()))", "(()())", "(())()", "()(())", "()()()" ] 解题思路 利用回溯的思想递归的生成括号.具体来说记录当前剩余左括号数left,剩余右括号数right,当前的生成括号字符串s,进行如下操作: 若left为0,说明左括

不积跬步无以至千里——LeetCode 22.括号生成

给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n = 3,生成结果为: [ "((()))", "(()())", "(())()", "()(())", "()()()" ] 原文地址:https://www.cnblogs.com/7long/p/10265818.html

[LeetCode系列]括号生成问题

给定n, 返回所有匹配的n对括号的可能形式. 如 给定 n = 3, 一个解集是: "((()))", "(()())", "(())()", "()(())", "()()()" 本题解法的思路是 使用栈seq保存经历的字符串状态; 使用栈valid保存对应的字符串中有效的括号对个数; 当seq不为空时(即回溯未结束): 当前的字符串和其中有效的括号对个数分别出栈; 1. 如果字符串长度等于待求解的长度,

22.括号生成

题目: 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n = 3,生成结果为: [ "((()))", "(()())", "(())()", "()(())", "()()()" ] 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/generate-parentheses 分析: 题目刚拿到的

【leetcode-22】括号生成

给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n = 3,生成结果为: [ "((()))", "(()())", "(())()", "()(())", "()()()"] 来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/generate-parentheses 回溯法 回溯算法基本思想:能进则

[LeetCode] Longest Consecutive Sequence(DP)

Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example,Given [100, 4, 200, 1, 3, 2], The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. Your algorithm should run in

LeetCode &quot;Minimum Path Sum&quot; - 2D DP

An intuitive 2D DP: dp[i][j] = min(grid[i-1][j-1] + dp[i-1][j], grid[i-1][j-1] + dp[i][j+1]) class Solution { public: int minPathSum(vector<vector<int> > &grid) { // dp[i][j] = min(dp[i-1][j] + dp[i][j], dp[i][j-1] + dp[i][j]); int n = gri

LeetCode &quot;Longest Palindromic Substring&quot; - 1D DP

2D DP is an intuitive solution of course, but I got an MLE error, so I simplified it into a 1D DP: class Solution { public: void goDp(vector<int> &dp, int &maxLen, int &is, int &ie, int startLen, int len, string &s) { for(int ile