首页 > 代码库 > 【leetcode】Generate Parentheses

【leetcode】Generate Parentheses

题目:

给定整数n,返回n对匹配的小括号字符串数组。

For example, given n = 3, a solution set is:

"((()))", "(()())", "(())()", "()(())", "()()()"

分析:

这种问题的模式是:1)问题的解有多个 ,2)每个解都是由多个有效的 ”步骤“ 组成的,3)变更以有解的某个或某些”步骤“ 可以形成新的解。这类问题差不多用dfs都能得到解决。
看看这个题目,括号只有两种 “("  ,")" ,初始第一个必须为"("。如果我们把初始的左括号视为二叉树的根节点,满足插入"("的条件我们就构建左子树,满足插入”)“的条件我们就构建右子树。

以N = 3为例,我们手动画下来所有的匹配组成就是这个。合法的括号匹配序列应该满足卡塔兰数性质。
那么这个问题就是深度遍历二叉树的过程了。与二叉树遍历不同的是访问左右子树时的判断条件,就是从根节点到当前结点形成的路径下,能否向左(加入”(“)或能否向右(加入”)“)。以及访问到路径终点的判断条件.

我们在进行括号匹配时,要遵循的原则是:在插入”)“时,前面必须有未匹配的”(“存在。在插入”(“时,必须已插入的”(“数量没达到给定值。

实现:

  void dfs(vector<string> &re, string& cur_re, int unmatched_lefts, int added_lefts, int n)
{
	
	if(unmatched_lefts == 0 && added_lefts == n)
	{
		re.push_back(cur_re);
	}

	if(unmatched_lefts > 0){//insert ')' is ok
		cur_re.append(1, ')');
		dfs(re, cur_re, unmatched_lefts - 1, added_lefts, n);
	}

	if(cur_re.size() > 0 && added_lefts < n)//can add another '(' 
	{
		cur_re.append(1,'(');
		dfs(re, cur_re, unmatched_lefts + 1, added_lefts + 1, n);	
	}
	cur_re.pop_back();
}
vector<string> generateParenthesis(int n) {

	vector<string> re;
	if(n <= 0)
		return re;
	string one_solve;
	one_solve.append(1, '(');
	dfs(re, one_solve, 1, 1, n);
	return re;
}