一 题目
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:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
二 分析
这个题目求输入n对括号的组合(成对匹配)。级别medium。
看了题目,括号的刚做了一个配对的题目。 leetcode 20. Valid Parentheses 那是用栈来校验的。
这个题目考察啥呢?一脸懵逼。
画了下组合结果,知道选择是n对括号,匹配嘛就是没有左括号就不能有右括号。满足条件:是左右括号都用完了。
还是卡住了,没思路,不知道怎么写?我尝试了下暴力循环,还要做匹配检查。1小时没做出来,放弃了。
后来网上看了大神的文章,使用递归(网上的别名回溯Backtracking 一个意思)。符合递归Recursion的三要素:1选择choice,2, 限制limit 3. return 条件。
为了计算左右括号数,我们定义两个变量left和right分别表示剩余左右括号的个数,字符串res 存放一条结果。
推导过程截图,老外讲的挺好的:https://www.youtube.com/watch?v=sz1qaKt0KGQ
主要是明确了返回条件:1 左右都用完了,及左侧剩余《右侧剩余。简单概括逻辑如下:
if(左右括号剩余为0|| 不匹配){
returnl;
}
if(左侧有剩余括号){
helper( left-1,right, res+"(")
}
if(右侧有括号){
helper( left,right-1, res+")")
}
还要考虑匹配的情况。
代码如下:
class Solution {
List<String> result = new ArrayList<>();
public List<String> generateParenthesis(int n) {
String res= "";
healper(n,n,res);
return result;
}
private void healper(int left, int right, String res) {
//返回条件
if(left<0|| right<0|| left>right){
return;
}
//rule
if(left==0&& right==0){
result.add(res);
return;
}
healper(left-1, right, res+"(") ;
healper(left, right-1, res+")") ;
}
}
Runtime: 1 ms, faster than 93.30% of Java online submissions for Generate Parentheses.
Memory Usage: 36 MB, less than 100.00% of Java online submissions forGenerate Parentheses.
这里res不传入递归,就是共享的变量,也是传入。
时间复杂度,不知道怎么算的,看下官网的solution介绍:我更直觉的是O(2^n).
参考:
https://zxi.mytechroad.com/blog/searching/leetcode-22-generate-parentheses/