22. Generate Parentheses

题目:

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

链接: http://leetcode.com/problems/generate-parentheses/

题解:

一样也是一道回溯题,可以dfs + 回溯,也可以用dp做。

下面是回溯。 Time Complexity -  n * Catalan number (n) ~ O(4n), Space Complexity O(n2)

public class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        if(n <= 0)
            return res;
        String str = new String();
        dfs(res, str, n, n);
        return res;
    }
    
    private void dfs(List<String> res, String str, int leftP, int rightP) {
        if(leftP > rightP)
            return;
        if(leftP == 0 && rightP == 0) {
            res.add(new String(str));
            return;
        }
        
        if(leftP >= 0)
            dfs(res, str + '(', leftP - 1, rightP);
        if(rightP >= 0)
            dfs(res, str + ')', leftP, rightP - 1);
    }
}

下面是DP解法,来自discussion的left.peter

一开始初始化Lists.get(0) = "", 之后对之前的lists做类似catalab number的操作 Cn = Σni=0 Ci Cn - i

Time Complexity - O(4n),  Space Complexity - O(n2)

public class Solution {
    public List<String> generateParenthesis(int n) {
        List<List<String>> lists = new ArrayList();
        lists.add(Collections.singletonList(""));
        
        for(int i = 1; i <= n; i++) {
            List<String> list = new ArrayList();
            
            for(int j = 0; j < i; j++) 
                for(String first : lists.get(j)) 
                    for(String second : lists.get(i - 1 - j))
                        list.add("(" + first + ")" + second);
                        
            lists.add(list);
        }
        
        return lists.get(lists.size() - 1);
    }
}

 

二刷:

Java:

这道题目一刷做得马马虎虎,现在来还债。 题目就是给定正整数n,求可以生成的括号的组合。这里我们采用dfs + backtracking,用来作buffer的StringBuilder里,先写入左括号,回溯,再写入右括号,回溯。计算Space Complexity的时候没有考虑最后的结果List

Time Complexity - O(2n), Space Complexity - O(n)    

public class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        if (n <= 0) {
            return res;
        }
        StringBuilder sb = new StringBuilder();
        generateParenthesis(res, sb, n, n);
        return res;
    }
    
    private void generateParenthesis(List<String> res, StringBuilder sb, int leftCount, int rightCount) {
        if (leftCount > rightCount) {
            return;
        }
        if (leftCount == 0 && rightCount == 0) {
            res.add(sb.toString());
            return;
        }
        if (leftCount >= 0) {
            sb.append('(');    
            generateParenthesis(res, sb, leftCount - 1, rightCount);
            sb.setLength(sb.length() - 1); 
        }
        if (rightCount >= 0) {
            sb.append(')');
            generateParenthesis(res, sb, leftCount, rightCount - 1);
            sb.setLength(sb.length() - 1); 
        }
    }
}

Python:

class Solution(object):
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        list = []
        str = ""
        self.getParenthesis(list, str, n, n)
        return list
        
    def getParenthesis(self, list, str, leftCount, rightCount):
        if leftCount > rightCount:
            return
        if leftCount == 0 and rightCount == 0:
            list.append(str)
            return
        if leftCount >= 0:
            self.getParenthesis(list, str + '(', leftCount - 1, rightCount)
        if rightCount >= 0:
            self.getParenthesis(list, str + ')', leftCount, rightCount - 1)

三刷:

方法和二刷一样,就是在dfs里面使用两个变量leftCount和rightCount来决定如何加括号。 注意在加括号前要判断leftCount和rightCount是否大于0, 并且之后要注意回溯。

Java:

Time Complexity - O(2n), Space Complexity - O(n)    

public class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        if (n <= 0) return res;
        generateParenthesis(res, new StringBuilder(), n, n);
        return res;
    }
    
    private void generateParenthesis(List<String> res, StringBuilder sb, int leftCount, int rightCount) {
        if (rightCount < leftCount) return;
        if (leftCount == 0 && rightCount == 0) res.add(sb.toString());
        
        if (leftCount > 0) {
            generateParenthesis(res, sb.append("("), leftCount - 1, rightCount);
            sb.setLength(sb.length() - 1);
        }
        if (rightCount > 0) {
            generateParenthesis(res, sb.append(")"), leftCount, rightCount - 1);
            sb.setLength(sb.length() - 1);
        }
    }
}

Reference:

https://leetcode.com/discuss/11509/an-iterative-method 

https://leetcode.com/discuss/14436/concise-recursive-c-solution

https://leetcode.com/discuss/25063/easy-to-understand-java-backtracking-solution

https://leetcode.com/discuss/18162/my-accepted-java-solution

https://leetcode.com/discuss/71960/ms-beats-92%25-submissions-easy-java-space-optimized-solution 

https://leetcode.com/discuss/66868/clean-python-dp-solution

https://leetcode.com/discuss/50698/my-java-code-using-dp

原文地址:https://www.cnblogs.com/yrbbest/p/4434626.html