zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    HDU 1982 Kaitou Kid The Phantom Thief (1)
    HDU 1984 Mispelling4
    HDU 2546 饭卡
    HDU 1009 FatMouse' Trade
    在VC 中如何隐藏一个主程序窗口
    .菜单项
    SetClassLong,GetClassLong 动态改变光标
    .窗口捕获鼠标
    .主窗口向子控件发送消息
    线段树 1698 Just a Hook 区间set更新
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4434626.html
Copyright © 2011-2022 走看看