组合的问题往往用DFS搜索,关键是如何组合能满足合法括号的条件,可以用图来进行思考:以n=3为例
A:由于n=3,只能有3个左括号,3个右括号,已经有了3个左括号,不能再放左括号了,故只能再往右侧走,得到((()))
B:同上,(()(已经有3个左括号了,只能再放右括号,往C走,得到(()())
D:(())(已有3个左括号了,只能放右括号,得到(())()
继续往后,可以得到剩余的组合
推到这里,也可以看出基本的思路:左括号次数为l,有括号次数为r,当l==n时左括号用完了,再往后增加n-r个右括号就得到了一个括号组合;若左括号没用完,则放左括号;只有当l>r时才可以放右括号,转换为代码如下:
class Solution {
public:
/*
* @param n: n pairs
* @return: All combinations of well-formed parentheses
*/
vector<string> generateParenthesis(int n) {
// write your code here
vector<string> result;
generate(result,n,"",0,0);//初始时左右括号次数为0
return result;
}
//DFS
void generate(vector<string>& result,int n,string s,int l,int r){
if(l==n){//左括号已经用完了,则要在后面追加右括号,这是收敛条件
result.push_back(s.append(n-r,')'));
return;
}
//进入到这里,说明l<n,则可以继续放左括号
generate(result,n,s+"(",l+1,r);
if(l>r)//可以放右括号
generate(result,n,s+")",l,r+1);
}
};