22. 括号生成
class Solution {
vector<string> Result_;
string Current_;
void DFS(int Left, int Right) {
if (Left == 0 && Right == 0) {
Result_.emplace_back(Current_);
return;
}
if (Left != 0) {
// Still can start new pair by using '('.
Current_.push_back('(');
DFS(Left - 1, Right);
Current_.pop_back();
}
if (Left < Right) {
// Must close the left paren by using ')'.
Current_.push_back(')');
DFS(Left, Right - 1);
Current_.pop_back();
}
}
public:
vector<string> generateParenthesis(int n) {
DFS(n, n);
return Result_;
}
};
看起来回溯题也不全是46. 全排列这种模板题,虽然因为DFS递归的性质,不动点仍然是需要的,但是最重要的是判定何时应该进行搜索的谓词。
在本题当中,谓词其实比较明确,就是「左括号只要有余就可以开启,但是右括号不能先于左括号进行闭合」,所以才会有Left != 0和Left < Right这两个看上去不对称的谓词,而这种不对称性是因为我们是自左向右线性考察字符串的,这一点很有意思。