题目:
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,表示有n对括号,请输出所有能够配对的括号组合
分析:
需要用到分治的思想,但是如何控制是个关键
设原问题为f(n)
原本想着将问题简化为 "()" + f(n-1),'(' + f(n- 1) + ')',再逐次递归下去,结果发现...
在 n = 4 的情况下,是无法得到 "(())(())" 的,
想了一上午,没有太大进展,连排列组合的模型都想试试了,中午在街上溜达了一圈,这个问题挥之不去,还是感觉哪里思路没有打开,回来之后,一度想要放弃,直接搜题解多好,干净利落!
但是内心还是很想再想想看,说不定会有别的思路
果然,回来坐了一会,有了一点思路
跳出括号这个具体的符号来看,其实就是两种字符(左括号和右括号),然后在能匹配的情况下,尝试各种组合情况,
注意,只有两种字符,那么只要控制好两种字符的个数,那么匹配肯定是能成功的!(具体控制往下看)
接下来的控制便是,每次递归中尝试在字符串末尾添加两种字符的任意一种,依次递归下去,直到两种字符的个数均等于n时终止并保存结果。在整个过程中,只要左起开始截止到任何位置处,左括号的数量不小于右括号,那么该字符串暂时是合法的,可以继续递归下去,否则终止该递归分支。
程序没有特别优化,运行的效率不怎么高,但是能够AC
几组数据
0
1
2
3
4
8
代码:(时间复杂度O(2^n))
class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<string> result;
if (n == 0) {
result.push_back("");
return result;
}
generator(n, n, "", result);
return result;
}
void generator(int left, int right, string current_string, vector<string> &result) {
if (left < 0 || right < 0 || left > right) {
return;
}
if (left == 0 && right == 0) {
result.push_back(current_string);
return;
}
string temp = current_string + '(';
generator(left - 1, right, temp, result);
temp = current_string + ')';
generator(left, right - 1, temp, result);
}
};