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:

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

链接:https://leetcode.com/problems/generate-parentheses/#/description

4/12/2017

3ms, 60%

我认为在我刷题之前这道题我肯定能做出来,现在反而一开始一点思路都没有了。还好这道题可以用backtracking来解决,所以掌握了方法是多么地重要。

注意的问题:

1. addParenthesis当中一定要把case的判断条件写详细。比如从第15行开始,最开始我的判断条件是if (left == n) {...} else {...},但是结果会溢出。为什么?因为{...}也许会有错误,导致根本不能确保left >= right,这只是我的猜想,应该不是最根本原因

 1 public class Solution {
 2     public List<String> generateParenthesis(int n) {
 3         List<String> ret = new ArrayList<>();
 4         if (n <= 0) return ret;
 5         StringBuilder sb = new StringBuilder();
 6         addParenthesis(0, 0, n, ret, sb);
 7         return ret;
 8     }
 9 
10     private void addParenthesis(int left, int right, int n, List<String> ret, StringBuilder sb) {
11         if (left == right && left == n) {
12             ret.add(sb.toString());
13             return;
14         }
15         if (left == right) {
16             sb.append('(');
17             addParenthesis(left + 1, right, n, ret, sb);
18             sb.deleteCharAt(sb.length() - 1);
19         } else if (left > right) {
20             if (left < n) {
21                 sb.append('(');
22                 addParenthesis(left + 1, right, n, ret, sb);
23                 sb.deleteCharAt(sb.length() - 1);
24             }
25             sb.append(')');
26             addParenthesis(left, right + 1, n, ret, sb);
27             sb.deleteCharAt(sb.length() - 1);
28         }
29     }
30 }

前面提到的错误的溢出解法,根本不能保证right比left小,也不能保证right比n小

 1 public class Solution {
 2     public List<String> generateParenthesis(int n) {
 3         List<String> ret = new ArrayList<>();
 4         if (n <= 0) return ret;
 5         StringBuilder sb = new StringBuilder();
 6         addParenthesis(0, 0, n, ret, sb);
 7         return ret;
 8     }
 9 
10     private void addParenthesis(int left, int right, int n, List<String> ret, StringBuilder sb) {
11         if (left == right && left == n) {
12             ret.add(sb.toString());
13             return;
14         }
15         if (left == n) {
16             sb.append(')');
17             addParenthesis(left, right + 1, n, ret, sb);
18             sb.deleteCharAt(sb.length() - 1);
19         } else {
20             sb.append(')');
21             addParenthesis(left, right + 1, n, ret, sb);
22             sb.deleteCharAt(sb.length() - 1);
23             sb.append('(');
24             addParenthesis(left + 1, right, n, ret, sb);
25             sb.deleteCharAt(sb.length() - 1);
26         }
27     }
28 }

别人的做法:

思路一致,更好看的写法

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

 1  public List<String> generateParenthesis(int n) {
 2         List<String> list = new ArrayList<String>();
 3         backtrack(list, "", 0, 0, n);
 4         return list;
 5     }
 6     
 7     public void backtrack(List<String> list, String str, int open, int close, int max){
 8         
 9         if(str.length() == max*2){
10             list.add(str);
11             return;
12         }
13         
14         if(open < max)
15             backtrack(list, str+"(", open+1, close, max);
16         if(close < open)
17             backtrack(list, str+")", open, close+1, max);
18     }

各种Python写法,更好的是,他提供了升级Python的一些建议:

https://discuss.leetcode.com/topic/17510/4-7-lines-python

I learned a lot by reading tutorials/docs and by looking at solutions of others at checkio.org (a Python programming site) and by spending a month on Python topics at Stackoverflow. Also, practice practice practice :-)

还提到了,我昨天刚研究到

http://docs.python-guide.org/en/latest/writing/gotchas/

其他人还用DP的做法,时间复杂度也许并不好:

https://discuss.leetcode.com/topic/3474/an-iterative-method

更多讨论:

https://discuss.leetcode.com/category/30/generate-parentheses

原文地址:https://www.cnblogs.com/panini/p/6701997.html