Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
X. DP
https://discuss.leetcode.com/topic/3474/an-iterative-method
For example, given n = 3, a solution set is:
[ "((()))", "(()())", "(())()", "()(())", "()()()" ]
X. DP
https://discuss.leetcode.com/topic/3474/an-iterative-method
First consider how to get the result f(n) from previous result f(0)...f(n-1).
Actually, the result f(n) will be put an extra () pair to f(n-1). Let the "(" always at the first position, to produce a valid result, we can only put ")" in a way that there will be i pairs () inside the extra () and n - 1 - i pairs () outside the extra pair.
Actually, the result f(n) will be put an extra () pair to f(n-1). Let the "(" always at the first position, to produce a valid result, we can only put ")" in a way that there will be i pairs () inside the extra () and n - 1 - i pairs () outside the extra pair.
Let us consider an example to get clear view:
f(0): ""
f(1): "("f(0)")"
f(2): "("f(0)")"f(1), "("f(1)")"
f(3): "("f(0)")"f(2), "("f(1)")"f(1), "("f(2)")"
So f(n) = "("f(0)")"f(n-1) , "("f(1)")"f(n-2) "("f(2)")"f(n-3) ... "("f(i)")"f(n-1-i) ... "(f(n-1)")"
The equation is equivalent to the following one:
f(n) = (f(0))f(n-1) + (f(1))f(n-2) + ... + (f(n-2))f(1) + (f(n-1))f(0)
First, let f(n) to be a correct solution set when there is n pair of parentheses.
This means every combination in f(n) is a valid combination, and any combination which isn't in f(n) is not a valid combination for n.
And we can easily get the first three solution sets i.e. f(0) = {""}, f(1) = {"()"} f(2) = {"()()", "(())"}.
This means every combination in f(n) is a valid combination, and any combination which isn't in f(n) is not a valid combination for n.
And we can easily get the first three solution sets i.e. f(0) = {""}, f(1) = {"()"} f(2) = {"()()", "(())"}.
For any n > 2, each combination of f(n) can be divided into two parts p0 and p1.
p0 and p1 has several properties:
p0 and p1 has several properties:
- Parentheses in both p0 and p1 can match wel
- p0 should be as short as possible but not empty. This means that p0 belongs to (f(l0-1)) where l0 is the number of pairs in p0.
This property can be proved easily. Shortest means the first left parenthesis in this combination always matches the last right parenthesis.
So without these two, what left is also a legal combination.
Now, let's reorganize f(n) by p0.
Put those combinations with same length of p0 into a same set, and then f(n) is divided into several subsets.
Each combination in subset s whose p0 has l0 pair of parentheses also belongs to the set (f(l0-1))f(n-l0).
So we can get f(n) belongs to (f(0))f(n-1) + (f(1))f(n-2) + ... + (f(n-2))f(1) + (f(n-1))f(0).
Put those combinations with same length of p0 into a same set, and then f(n) is divided into several subsets.
Each combination in subset s whose p0 has l0 pair of parentheses also belongs to the set (f(l0-1))f(n-l0).
So we can get f(n) belongs to (f(0))f(n-1) + (f(1))f(n-2) + ... + (f(n-2))f(1) + (f(n-1))f(0).
OK, the only thing to prove now is (f(0))f(n-1) + (f(1))f(n-2) + ... + (f(n-2))f(1) + (f(n-1))f(0) also belongs to f(n).
Notice that each combination in (f(i))f(n-1-i) is a legal combination for n, and we've declared before that each legal combination for n belongs to f(n).
So each combination in the left side of equation belongs to f(n), and the left side as a whole set belongs to f(n).
Notice that each combination in (f(i))f(n-1-i) is a legal combination for n, and we've declared before that each legal combination for n belongs to f(n).
So each combination in the left side of equation belongs to f(n), and the left side as a whole set belongs to f(n).
public List<String> generateParenthesis(int n)
{
List<List<String>> lists = new ArrayList<>();
lists.add(Collections.singletonList(""));
for (int i = 1; i <= n; ++i)
{
final List<String> list = new ArrayList<>();
for (int j = 0; j < i; ++j)
{
for (final String first : lists.get(j))
{
for (final String second : lists.get(i - 1 - j))
{
list.add("(" + first + ")" + second);
}
}
}
lists.add(list);
}
return lists.get(lists.size() - 1);
}
https://discuss.leetcode.com/topic/20880/my-java-code-using-dp
The idea is clear. Use cache to store the already calculated results, from f(0) to f(n). For each f(i), get f(j) and f(i - j - 1) from cache, 0 <= j < = j-1.
public static List<String> generateParenthesis(int n) {
List<List<String>> cache = new LinkedList<>(); // use arraylist or map
cache.add(Arrays.asList(""));
for (int i = 1; i <= n; i++) {
List<String> nList = new LinkedList<>();
for (int j = 0; j < i; j++) {
List<String> inside = cache.get(j);
List<String> tail = cache.get(i - j - 1);
for (int k = 0; k < inside.size(); k++) {
for (int l = 0; l < tail.size(); l++) {
nList.add("(" + inside.get(k) + ")" + tail.get(l));
}
}
}
cache.add(nList);
}
return cache.get(n);
}
X. BFS - Using Queue
https://richdalgo.wordpress.com/2014/12/21/generate-parentheses-bfs-dfs/
http://blog.sina.com.cn/s/blog_b9285de20101oa9t.html
http://blog.sina.com.cn/s/blog_b9285de20101oa9t.html
class Elem {
int left;
int right;
String str;
Elem(int l, int r, String s) {
left = l;
right = r;
str = s;
}
}
public List<String> generateParenthesis(int n) {
List<String> result = new ArrayList<String>();
Queue<Elem> queue = new LinkedList<Elem>();
queue.add(new Elem(0,0,""));
while (!queue.isEmpty()) {
Elem elem = queue.poll();
if (elem.left == elem.right && elem.left == n) {
result.add(elem.str);
}
if (elem.left >= elem.right && elem.left < n) {
queue.add(new Elem(elem.left+1, elem.right, elem.str + "("));
}
if (elem.left >= elem.right && elem.right < n) {
queue.add(new Elem(elem.left, elem.right+1, elem.str + ")"));
}
}
return result;
}
find the last occurrence position P of '(' in the previous result, and append '(' + the rest + ')' to it from P+1 to end;
- vector<string> generateParenthesis(int n)
- {
- vector<string> res;
- res.push_back("");
- for(int i=0;i<n;i++)
- {
- vector<string> tmp;
- for(int j=0;j<res.size();j++)
- {
- int pos = res[j].rfind('(');
- for(int k=pos+1;k<=res[j].size();k++)
- {
- tmp.push_back(res[j].substr(0,k) +
- '(' + res[j].substr(k) + ')');
- }
- }
- res = tmp;
- }
- return res;
- }
public List<String> generateParenthesis(int n) { ArrayList<String> result = new ArrayList<String>(); ArrayList<Integer> diff = new ArrayList<Integer>(); result.add(""); diff.add(0); for (int i = 0; i < 2 * n; i++) { ArrayList<String> temp1 = new ArrayList<String>(); ArrayList<Integer> temp2 = new ArrayList<Integer>(); for (int j = 0; j < result.size(); j++) { String s = result.get(j); int k = diff.get(j); if (i < 2 * n - 1) { temp1.add(s + "("); temp2.add(k + 1); } if (k > 0 && i < 2 * n - 1 || k == 1 && i == 2 * n - 1) { temp1.add(s + ")"); temp2.add(k - 1); } } result = new ArrayList<String>(temp1); diff = new ArrayList<Integer>(temp2); } return result; }
For n=2, we can construct the result set by inserting a new pair “()” into all gaps in the each of the result from n=1. For example, for n=1 result = {()} that has only one solution () that has total 3 gaps as follows –
( ) ^ ^ ^ g1 g2 g3
So, In order to get result for n=2 we will append () in each gap of each of the solutions of n=1 as follows –
()() (()) ()() ^ ^ ^ g1 g2 g3
The final result set (unique elements) for n=2 would be {()(), (())}.
So, in general there are m+1 gaps in a parenthesis of length m. So, we can construct the string with n parenthesis by inserting “()” into each of the m+1 gaps of the each of the solution of length m in result set for n-1.
How to implement this? We can formulate this problem as a Tree traversal problem where starting from n=1 as root “()” we traverse m+1=2+1=3 children corresponding to the string constructed by inserting “()” into each of the m+1 gaps. So, nodes at a level n of this tree will contain all possible strings with n pair of parenthesis. For
( ) <- n = 1 / | \ ( ) ( ) (()) ()() <- n = 2 / | \ \ \ ()()() (())() ......... <- n = 3
So, we can do a level order traversal using a queue and stop at level = n at which point the queue will contains the result set for n.
public static ArrayList<String> genParanthesis(int n){ ArrayList<String> res = new ArrayList<String>(); if(n <= 0){ return res; } if(n == 1){ res.add("()"); return res; } Queue<StringBuilder> queue = new ArrayDeque<StringBuilder>(); Set<String> visited = new HashSet<String>(); queue.add(new StringBuilder("()")); int count = 1; int level = 1; //do a level order (BFS) trversal upto level=n while(!queue.isEmpty()){ StringBuilder node = queue.poll(); String cur = node.toString(); count--; visited.add(cur); //at the end of level order traversal upto level n the queue will contain all the leaves at level n //which are basically all possible strings constructed with n pair of parenthesis if(level == n){ res.add(cur); continue; } //if not reached level n yet, then do BFS level order //there are total 1+len(cur) gaps for(int gap = 0; gap < cur.length()+1; gap++){ //we create a child by putting () to each of the gap positions StringBuilder child = new StringBuilder(cur).insert(gap, "()"); if(!visited.contains(child.toString())){ queue.add(child); visited.add(child.toString()); } } //end of a level if(count == 0){ level++; count = queue.size(); } } return res; }
Alternative Recursive Approach
The idea is to keep two counters, one for number of remaining left parenthesis and the other for total number of remaining right parenthesis to be added. Each time we add a right parenthesis if remaining is greater than 0. We also balance it by adding left parenthesis only if remaining right is greater than 0. Below is the implementation of this algorithm.
public List<String> generateParenthesis(int n) { ArrayList<String> res = new ArrayList<String>(); if(n <= 0){ return res; } generate("", n, 0, res); return res; } public void generate(String str, int left, int right, ArrayList<String> res){ if(right == 0 && left == 0){ res.add(str); } if(right > 0){ generate(str+")", left, right-1, res); } if(left > 0){ generate(str+"(", left-1, right+1, res); // left-1??? } }
===>like bfs, but not good implementation
public
ArrayList<String> generateParenthesis(
int
n) {
ArrayList<Set<String>> list =
new
ArrayList<Set<String>>();
int
number=
1
;
while
(number<=n){
Set<String> parentheses =
new
HashSet<string>();
//generate combinations of pattern "("+[number-1]+")"
generateParentheses(number,list,parentheses);
//generate combinations of pattern [1][number-1],[2][number-2],...[number-1][1]
for
(
int
i=
1
;i<number;i++){
int
leftIndex=i-
1
;
int
rightIndex=number-i-
1
;
for
(String left:list.get(leftIndex)){
for
(String right:list.get(rightIndex)){
parentheses.add(left+right);
}
}
}
//add results of this number and go on.
list.add(parentheses);
number++;
}
//add the elements to list required by OJ.
ArrayList<String> result =
new
ArrayList<String>();
Iterator<String> it = list.get(list.size()-
1
).iterator();
while
(it.hasNext())
result.add(it.next());
return
result;
}
private
void
generateParentheses(
int
number,ArrayList<Set<String>> list,Set<String> parentheses){
if
(number==
1
){
parentheses.add(
"()"
);
return
;
}
StringBuilder sb =
new
StringBuilder();
for
(String s:list.get(number-
2
)){
sb.append(
"("
);
sb.append(s);
sb.append(
")"
);
parentheses.add(sb.toString());
sb.setLength(
0
);
}
}
}
http://www.programcreek.com/2014/01/leetcode-generate-parentheses-java/
public List<String> generateParenthesis(int n) { ArrayList<String> result = new ArrayList<String>(); ArrayList<Integer> diff = new ArrayList<Integer>(); result.add(""); diff.add(0); for (int i = 0; i < 2 * n; i++) { ArrayList<String> temp1 = new ArrayList<String>(); ArrayList<Integer> temp2 = new ArrayList<Integer>(); for (int j = 0; j < result.size(); j++) { String s = result.get(j); int k = diff.get(j); if (i < 2 * n - 1) { temp1.add(s + "("); temp2.add(k + 1); } if (k > 0 && i < 2 * n - 1 || k == 1 && i == 2 * n - 1) { temp1.add(s + ")"); temp2.add(k - 1); } } result = new ArrayList<String>(temp1); diff = new ArrayList<Integer>(temp2); } return result; } |
X. DFS
Same idea, but instead of expensive string concatenation, I used StringBuilder and backtrack when necessary, mainly for efficiency.
X. DFS+Cache
https://discuss.leetcode.com/topic/33127/java-easy-to-understand-recursive-dp-method-with-explanations
For each valid parenthesis, there must be a pair whose right parenthesis is at the rightmost location. Thus, a valid parenthesis has to be of the following form:
* ( * )
where
*
denotes the remaining parentheses which are don't yet know (*
can be empty, i.e., with 0 pair of parenthesis). However, we do know the following two important facts:- both two
*
are valid parentheses; - they don't overlap at all! (a pair has to be either on the left side or inside
()
, but cannot be the case where(
is on the left side and)
is inside()
)
If we put
i
parentheses inside ()
, there are n-i-1
to be put on the left side. This gives us a recursive formula as below:P(n) = P(n-i-1) x P(i)
where
P(n)
are all valid parentheses with n
parentheses.public List<String> generateParenthesis(int n) {
List<String>[] lists = new LinkedList[n+1]; // store all P(k)'s for k=0,1,...,n
return helper(n, lists);
}
private List<String> helper(int n, List<String>[] lists) {
if(lists[n]!=null) return lists[n]; // if computed, reuse
List<String> res = new LinkedList<String>();
if(n<=0) {
lists[0] = new LinkedList<String>(Arrays.asList(""));
return lists[0];
}
else if(n==1) {
lists[1] = new LinkedList<String>(Arrays.asList("()"));
return lists[1];
}
// the following simply implements the recursive formula derived above
for(int i=0; i<=n-1; i++) {
List<String> left = helper(n-i-1, lists);
List<String> inside = helper(i, lists);
for(String str1 : left) {
for(String str2 : inside) {
res.add(str1 + "(" + str2 + ")");
}
}
}
lists[n] = res; // store computed results for reuse
return res;
}
public List<String> generateParenthesis(int n) {
List<String> result = new ArrayList<String>();
if (n == 0) {
result.add("");
} else {
for (int i = n - 1; i >= 0; i--) {
List<String> insertSub = generateParenthesis(i);
List<String> tailSub = generateParenthesis(n - 1 - i);
for (String insert : insertSub) {
for (String tail : tailSub) {
result.add("(" + insert + ")" + tail);
}
}
}
}
return result;
}
https://fullengineer.wordpress.com/2015/05/18/generate-parentheses-leetcode/
https://discuss.leetcode.com/topic/23229/java-dfs-way-solution
Use DFS to generate parentheses. We need to keep track of number of ‘(‘ and number of ‘)’ .
Always generate ‘(‘ first and then ‘)’ . And if number of ‘(‘ has to be more or equals than number of ‘)’.
Always generate ‘(‘ first and then ‘)’ . And if number of ‘(‘ has to be more or equals than number of ‘)’.
Running time complexity is O(n!) . First let’s assume there is no valid parentheses rule. For each position we can either place ( or ) . Running time would be 2^n . Since there is rule, once we put ( in the place , the next position will be limited. So it is n! . ???? incorrect
https://discuss.leetcode.com/topic/23229/java-dfs-way-solution
public List<String> generateParenthesis(int n)
{
List<String> result = new LinkedList<String>();
if (n > 0) generateParenthesisCore("", n, n, result);
return result;
}
private void generateParenthesisCore(String prefix, int left, int right, List<String> result)
{
if (left == 0 && right == 0) result.add(prefix);
// Has left Parenthesis
if (left > 0) generateParenthesisCore(prefix+'(', left-1, right, result);
// has more right Parenthesis
if (left < right) generateParenthesisCore(prefix+')', left, right-1, result);
}
给定的n为括号对,所以就是有n个左括号和n个右括号的组合。
按顺序尝试知道左右括号都尝试完了就可以算作一个解。
注意,左括号的数不能大于右括号,要不然那就意味着先尝试了右括号而没有左括号,类似“)(” 这种解是不合法的。
1 public ArrayList<String> generateParenthesis(int n) {
2 ArrayList<String> res = new ArrayList<String>();
3 String item = new String();
4
5 if (n<=0)
6 return res;
7
8 dfs(res,item,n,n);
9 return res;
10 }
11
12 public void dfs(ArrayList<String> res, String item, int left, int right){
13 if(left > right)//deal wiith ")("
14 return;
15
16 if (left == 0 && right == 0){
17 res.add(new String(item));
18 return;
19 }
20
21 if (left>0)
22 dfs(res,item+'(',left-1,right);
23 if (right>0)
24 dfs(res,item+')',left,right-1);
25 }
2 ArrayList<String> res = new ArrayList<String>();
3 String item = new String();
4
5 if (n<=0)
6 return res;
7
8 dfs(res,item,n,n);
9 return res;
10 }
11
12 public void dfs(ArrayList<String> res, String item, int left, int right){
13 if(left > right)//deal wiith ")("
14 return;
15
16 if (left == 0 && right == 0){
17 res.add(new String(item));
18 return;
19 }
20
21 if (left>0)
22 dfs(res,item+'(',left-1,right);
23 if (right>0)
24 dfs(res,item+')',left,right-1);
25 }
Use String builder
public List<String> generateParenthesis(int n) {
List<String> result=new ArrayList<String> ();
if (n<1){
return result;
}
int leftNum=n;
int rightNum=n;
StringBuffer current=new StringBuffer();
buildResult(leftNum, rightNum, current, result);
return result;
}
private void buildResult(int leftNum, int rightNum, StringBuffer current, List<String> result){
// if both sides number of parenthese equal to 0, then we got an valid result
if (leftNum==0 && rightNum==0){
result.add(current.toString());
return;
}
// if number of left Parenthese bigger than 0, then add one left parenthese and
// keep builResult from there
if (leftNum>0){
current.append('(');
buildResult(leftNum-1, rightNum, current, result);
current.deleteCharAt(current.length()-1); // backtrack undo the change
}
// if number of right parenthese bigger than left, then add one right parenthese and
// builResult from there
if (rightNum>leftNum){
current.append(')');
buildResult(leftNum, rightNum-1, current, result);
current.deleteCharAt(current.length()-1);//\\
}
}
setLength is cheaper then deleteCharAt
public List<String> generateParenthesis(int n) {
List<String> res = new ArrayList<>();
helper(res, new StringBuilder(), 0, 0, n);
return res;
}
private void helper(List<String> res, StringBuilder sb, int open, int close, int n) {
if(open == n && close == n) {
res.add(sb.toString());
return;
}
if(open < n) {
sb.append("(");
helper(res, sb, open+1, close, n);
sb.setLength(sb.length()-1);
}
if(close < open) {
sb.append(")");
helper(res, sb, open, close+1, n);
sb.setLength(sb.length()-1);
}
}
If l==r==n, return the current string, where l and r is the number of left and right parentheses, respectively. Actually, if l==n, meaning that we have used up all left parentheses, we can simply append all of the rest of right parentheses and then return the string.
Recursion part:
If l==r<n, we can only append a left parenthesis;
Otherwise, we can append either one.
Recursion part:
If l==r<n, we can only append a left parenthesis;
Otherwise, we can append either one.
private void generator(int n, int l, int r, StringBuilder ss, ArrayList<String> resSet) {
if (l==n) {
while (r++ < n) ss = ss.append(")");
resSet.add(ss.toString());
} else if (l==r) {
generator(n, l+1, r, ss.append('('), resSet);
} else {
int oldlen = ss.length();
generator(n, l+1, r, ss.append('('), resSet);
ss = ss.delete(oldlen, ss.length());
generator(n, l, r+1, ss.append(')'), resSet);
}
}
public ArrayList<String> generateParenthesis(int n) {
ArrayList<String> resSet = new ArrayList<String>();
generator(n, 0, 0, new StringBuilder(), resSet);
return resSet;
}
Notice that we use StringBuilder rather than String to improve the performance (see discussion here).
Also, since Java methods pass pointers to objects, the content of object may be modified in the method (see discussion here). In the case here, we need to clean up the StringBuilder when we want to append other things.
Also, since Java methods pass pointers to objects, the content of object may be modified in the method (see discussion here). In the case here, we need to clean up the StringBuilder when we want to append other things.
private void dfs(int n, int l, int r, StringBuffer sb, List<String> pare){ if(r > l || l > n || r > n) return; if(l == n && r == n){ pare.add(new String(sb)); return; } sb.append('('); dfs(n, l + 1, r, sb, pare); sb.deleteCharAt(l + r); // set(length-1, ')') sb.append(')'); dfs(n, l, r + 1, sb, pare); sb.deleteCharAt(l + r); }
public void helper(int n, int l, int r, String s, ArrayList<String> result) {
if (l == n) {
while (r < n) {
s += ")";
r++;
}
result.add(s);
return;
}
if (l < n) {
helper(n, l + 1, r, s+"(", result);
}
if (r < l) {
helper(n, l, r + 1, s+")", result);
}
}
http://blog.welkinlan.com/2015/04/13/generate-parentheses-leetcode-java/Use char array
public ArrayList<String> generateParenthesis(int n) {
ArrayList<String> result = new ArrayList<String>();
char[] clause = new char[n+n];
recursiveGeneration(result, 0, 0, n, clause);
return result;
}
public void recursiveGeneration(ArrayList<String> result, int left /*how many "(" used*/, int right /*how many ")" used*/, int n, char[] clause){
//if all "(" and ")" have been used, output the result
if (left == n && right == n) {
result.add(new String(clause));
return;
}
//if there are available "("s, it is always safe to set "(" at this position.
if (left < n) {
clause[left + right] = '(';
recursiveGeneration(result, left + 1, right, n, clause);
}
//after we have generated all the results for the "(" case, we could try to put a ")" at this position.
//Only if there are fewer ")"s used than "("s, can we set ")" at this position.
//Otherwise, it's not possible to generate a valid parenthesis afterwards
if (right < left) {
clause[left + right] = ')';
recursiveGeneration(result, left, right + 1, n, clause);
}
}
https://leetcode.com/discuss/71960/ms-beats-92%25-submissions-easy-java-space-optimized-solution
Don't need the int i => open, close is enough.
public List<String> generateParenthesis(int n) { List<String> res = new ArrayList<>(); char[] perm = new char[n*2]; perms(n, n, perm, 0, res); return res; } private void perms(int open, int close, char[] perm, int i, List<String> res) { if (i == perm.length) { res.add(new String(perm)); return; } if (open > 0 && close >= open) { perm[i] = '('; perms(open - 1, close, perm, i+1, res); } if (close > 0) { perm[i] = ')'; perms(open, close - 1, perm, i+1, res); } }
https://github.com/Chang-Hu/Algorithm-Practice/blob/master/Generate%20Parentheses.java
Don't need the int i => open, close is enough.
public List<String> generateParenthesis(int n) { List<String> res = new ArrayList<>(); char[] perm = new char[n*2]; perms(n, n, perm, 0, res); return res; } private void perms(int open, int close, char[] perm, int i, List<String> res) { if (i == perm.length) { res.add(new String(perm)); return; } if (open > 0 && close >= open) { perm[i] = '('; perms(open - 1, close, perm, i+1, res); } if (close > 0) { perm[i] = ')'; perms(open, close - 1, perm, i+1, res); } }
https://github.com/Chang-Hu/Algorithm-Practice/blob/master/Generate%20Parentheses.java
Return result list: - creating too many temp list
public ArrayList<String> generateParenthesis(int n) {
if (n == 0) {
return new ArrayList<String>();
}
return helper(n, 0, 0, new StringBuilder());
}
public ArrayList<String> helper(int n, int l, int r, StringBuilder s) {
ArrayList<String> result = new ArrayList<String>();
if (l > n || r > n) {
return result;
}
if (r == n) {
result.add(s.toString());
}
if (l < n) {
StringBuilder ss = new StringBuilder(s);
ss.append("(");
result.addAll(helper(n, l + 1, r, ss));
}
if (r < l) {
StringBuilder ss = new StringBuilder(s);
ss.append(")");
result.addAll(helper(n, l, r + 1, ss));
}
return result;
}
05 | vector<string> generateParenthesis ( int n) { |
06 | if (n == 0) return vector<string>(1, "" ); |
07 | if (n == 1) return vector<string> (1, "()" ); |
08 | vector<string> result; |
09 |
10 | for ( int i = 0; i < n; ++i) |
11 | for (auto inner : generateParenthesis (i)) |
12 | for (auto outer : generateParenthesis (n - 1 - i)) |
13 | result.push_back ( "(" + inner + ")" + outer); |
14 |
15 | return result; |
16 | } |
05 | vector<string> generateParenthesis( int n) { |
06 | vector<string> result; |
07 | if (n > 0) generate(n, "" , 0, 0, result); |
08 | return result; |
09 | } |
10 | // l 表示 ( 出现的次数, r 表示 ) 出现的次数 |
11 | void generate( int n, string s, int l, int r, vector<string> &result) { |
12 | if (l == n) { |
13 | result.push_back(s.append(n - r, ')' )); |
14 | return ; |
15 | } |
16 | generate(n, s + '(' , l + 1, r, result); |
17 | if (l > r) generate(n, s + ")" , l, r + 1, result); |
18 | } |
Write a function to generate all possible n pairs of balanced parentheses.
void
printParenthesis(
int
n)
{
if
(n > 0)
_printParenthesis(0, n, 0, 0);
return
;
}
void
_printParenthesis(
int
pos,
int
n,
int
open,
int
close)
{
static
char
str[MAX_SIZE];
if
(close == n)
{
printf
(
"%s \n"
, str);
return
;
}
else
{
if
(open > close) {
str[pos] =
'}'
;
_printParenthesis(pos+1, n, open, close+1);
}
if
(open < n) {
str[pos] =
'{'
;
_printParenthesis(pos+1, n, open+1, close);
}
}
}
EPI Solution
Enumerate strings of balanced parenthesis GenerateParentheses.java
public static List<String> generateParentheses(int n) {String s = "";
List<String> result = new ArrayList<>();
generateParenthesesHelper(2 * n, 0, s, result);
return result;
}
private static void generateParenthesesHelper(int remained, int leftParens,
String s, List<String> result) {
if (remained == 0) {
result.add(s);
return;
}
if (leftParens < remained) { // Able to insert '('.
generateParenthesesHelper(remained - 1, leftParens + 1, s + "(", result);
}
if (leftParens > 0) { // Able to insert ')'.
generateParenthesesHelper(remained - 1, leftParens - 1, s + ")", result);
}
}
http://stackoverflow.com/questions/24704170/generate-balanced-parentheses-in-java
public class generateParentheses {
public static ArrayList<String> generateParenthesis(int n) {
ArrayList<String> result = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
generate(n, 0, 0, result, sb);
return result;
}
public static void generate(int n, int left, int right, ArrayList<String> result,
StringBuilder sb) {
if (left < right) {
return;
}
if (left == n && right == n) {
result.add(sb.toString());
//sb.delete(0,sb.length());
return;
}
if (left == n) {
generate(n, left, right + 1, result, sb.append(')'));
//delete current ')'.
sb.delete(sb.length() - 1, sb.length());
return;
}
generate(n, left + 1, right, result, sb.append('('));
//delete current '(' after you finish using it for next recursion.
sb.delete(sb.length() - 1, sb.length());
generate(n, left, right + 1, result, sb.append(')'));
//same as above here.
sb.delete(sb.length() - 1, sb.length());
}
X. Using Stackhttps://discuss.leetcode.com/topic/1921/does-anyone-come-up-with-a-non-recursion-solution/5
X. Misc
https://leetcode.com/discuss/18162/my-accepted-java-solution
For 2, it should place one "()" and add another one insert it but none tail it,
'(' f(1) ')' f(0)
or add none insert it but tail it by another one,
'(' f(0) ')' f(1)
Thus for n, we can insert f(i) and tail f(j) and i+j=n-1,
'(' f(i) ')' f(j)
I think you can add a cache to improve performance; so for the same n, you only need to calculate once.
public List<String> generateParenthesis(int n) {
List<String> result = new ArrayList<String>();
if (n == 0) {
result.add("");
} else {
for (int i = n - 1; i >= 0; i--) {
List<String> insertSub = generateParenthesis(i);
List<String> tailSub = generateParenthesis(n - 1 - i);
for (String insert : insertSub) {
for (String tail : tailSub) {
result.add("(" + insert + ")" + tail);
}
}
}
}
return result;
}
( ()) -> (()()) I* inserted pair after 1st left paren */
-> ((())) /* ins erted pair after 2nd left paren */
-> ()(()) /* inserted pair at beginning of string*/
() () -> (())() /* inserted pair after 1st left paren */
-> ()(()) /* ins erted pair after 2nd left paren */
-> () () () /* inserted pair at beginning of string*/
But wait-we have some duplicate pairs listed. The string () ( ()) is listed twice.
-- We waste a lot of time coming up with the duplicate strings.
Set<String> generateParens (int remaining) {
Set<String> set= new HashSet<String>();
if (remaining== 0) {
set.add("");
} else {
Set<String> prev = generateParens(remaining - 1);
for (String str : prev) {
for (int i= 0; i < str.length(); i++) {
if (str.charAt(i) == '(') {
String s = insertlnside(str, i);
/*Add s to set if it's not already in there. Note: HashSet
* automatically checks for duplicates before adding, so an explicit
* check is not necessary. */
set.add(s);
}
}
set.add("()" + str);
}
}
return set;
}
String insertlnside(String str, int leftlndex) {
String left = str.substring(0, leftlndex + 1);
String right = str.substring(leftindex + 1, str.length());
return left + "()" + right;
}
X.
void addParen(Arraylist<String> list, int leftRem, int rightRem, char[] str,
int index) {
if (leftRem < 0 || rightRem < leftRem) return; // invalid state
if (leftRem == 0 && rightRem == 0) {/*Out of left and right parentheses */
list.add(String.valueOf(str));
} else {
str[index] = '('; // Add left and recurse
addParen(list, leftRem - 1, rightRem, str, index + 1);
str[index] = ')'; // Add right and recurse
addParen(list, leftRem, rightRem - 1, str, index + 1);
}
}
ArrayList<String> generateParens(int count) {
char[] str = new char[count *2];
Arraylist<String> list = new Arraylist<String>();
addParen(list, count, count, str, 0);
return list;
}
X. BFS
https://discuss.leetcode.com/topic/1921/does-anyone-come-up-with-a-non-recursion-solution/10
public static List<String> generateParenthesis(int n) {
List<String>[] result = new List[n+1];
result[0] = Arrays.asList("");
for(int i=1; i<=n; i++){
List<String> r = new ArrayList<String>();
for(int j=0; j<i; j++){
for(String sl : result[j])
for(String sr : result[i-j-1])
r.add("(" + sl + ")" + sr);
}
result[i] = r;
}
return result[n];
}
https://leetcode.com/discuss/25063/easy-to-understand-java-backtracking-solution
-- Waste too much space
public List<String> generateParenthesis(int n)
{
List<List<String>> lists = new ArrayList<>();
lists.add(Collections.singletonList(""));
for (int i = 1; i <= n; ++i)
{
final List<String> list = new ArrayList<>();
for (int j = 0; j < i; ++j)
{
for (final String first : lists.get(j))
{
for (final String second : lists.get(i - 1 - j))
{
list.add("(" + first + ")" + second);
}
}
}
lists.add(list);
}
return lists.get(lists.size() - 1);
}
X. https://leetcode.com/articles/generate-parentheses/
Approach 3: Closure Number
Intuition
To enumerate something, generally we would like to express it as a sum of disjoint subsets that are easier to count.co
Consider the closure number of a valid parentheses sequence
S
: the least index >= 0
so that S[0], S[1], ..., S[2*index+1]
is valid. Clearly, every parentheses sequence has a unique closure number. We can try to enumerate them individually.
Algorithm
For each closure number
c
, we know the starting and ending brackets must be at index 0
and 2*c + 1
. Then, the 2*c
elements between must be a valid sequence, plus the rest of the elements must be a valid sequence.
public List<String> generateParenthesis(int n) {
List<String> ans = new ArrayList();
if (n == 0) {
ans.add("");
} else {
for (int c = 0; c < n; ++c)
for (String left : generateParenthesis(c))
for (String right : generateParenthesis(n - 1 - c))
ans.add("(" + left + ")" + right);
}
return ans;
}
We can generate all sequences of
'('
and ')'
characters. Then, we will check if each one is valid.
Algorithm
To generate all sequences, we use a recursion. All sequences of length
n
is just '('
plus all sequences of length n-1
, and then ')'
plus all sequences of length n-1
.
To check whether a sequence is valid, we keep track of
balance
, the net number of opening brackets minus closing brackets. If it falls below zero at any time, or doesn't end in zero, the sequence is invalid - otherwise it is valid- Time Complexity : . For each of sequences, we need to create and validate the sequence, which takes work.
- Space Complexity : . Naively, every sequence could be valid. See Approach 3 for development of a tighter asymptotic bound
public List<String> generateParenthesis(int n) {
List<String> combinations = new ArrayList();
generateAll(new char[2 * n], 0, combinations);
return combinations;
}
public void generateAll(char[] current, int pos, List<String> result) {
if (pos == current.length) {
if (valid(current))
result.add(new String(current));
} else {
current[pos] = '(';
generateAll(current, pos + 1, result);
current[pos] = ')';
generateAll(current, pos + 1, result);
}
}
public boolean valid(char[] current) {
int balance = 0;
for (char c : current) {
if (c == '(')
balance++;
else
balance--;
if (balance < 0)
return false;
}
return (balance == 0);
}