LeetCode 22. 括号生成
题目描述
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例
示例 1:
输入:n = 3 输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:
输入:n = 1 输出:["()"]
解法
1.回溯法
解题思路
回溯的第一步是对一颗满二叉树进行深度优先遍历,我们先写出一个有终止条件的简单深度优先遍历的代码:
class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<string> ans;
if(n <= 0) return ans;
auto dfs = [&](this auto && dfs,string path){
if(path.size() == 2 * n){
ans.push_back(path);
return;
}
dfs(path + '(');
dfs(path + ')');
};
dfs("");
return ans;
}
};

上面这段代码因为有path.size() == 2 * n这个终止条件,返回的结果满足了path长度这一条件,没有满足左括号个数等于右括号个数这第二个条件,也没有满足遍历过程中左括号个数要大于等于右括号个数(完成闭合的必要条件)这第三个条件。于是我们需要在把path装入ans前要保证path满足以上提到的每一个条件。
我们需要添加left和right这两个局部变量,记录当前path中的"("和")"的个数。然后添加if(left > n || right > left) return;这一终止条件,就可以得到预期结果。
class Solution {
public:vector<string> generateParenthesis(int n) {vector<string> ans;if(n <= 0) return ans;auto dfs = [&](this auto && dfs,string path,int left,int right){if(left > n || right > left) return; //right > left 用来排除‘)’在前面的情况if(path.size() == 2 * n){ans.push_back(path);return;}dfs(path + '(',left + 1,right);dfs(path + ')',left,right + 1);};dfs("",0,0);return ans;}
};时间复杂度O(LogN),空间复杂度O(1)
