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:
[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
没有明确给出.
我把字符串的每一个位置都看做是一个节点,根节点就是’(‘,而之后的每一个位置都有两种情况:
1.放置左括号’(‘,放置条件是左括号的数目小于n;
2.放置右括号’)’,放置条件是祖先节点中左括号的数目大于右括号。
做的时候,我按照这个思路画了一个n=3的树图,如下:
(
/ \
( )
/ \ \
( ) (
\ / \ / \
) ( ) ( )
\ \ / \ /
) ) ( ) (
\ \ \ \ \
) ) ) ) )
图画得很丑,将就一下吧,⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄。反正就是一棵树,在画的过程中,会发现就是一个递归的过程,对于每一个节点,都判断那两个条件是否满足,满足的话生成对应的一个子节点。而递归的结束条件就是右括号的数目等于n。
所以实现的时候,我通过递归实现,参数是当前祖先节点构成的s跟祖先节点中的左括号数目以及祖先节点中的右括号数目。函数体就是判断结束条件,以及判断添加子节点的两个条件:
void generator(string s, int left, int right) {
if (right == number)
result.push_back(s);
if (left > right)
generator(s + ")", left, right + 1);
if (left < number)
generator(s + "(", left + 1, right);
}
通过之后看了Discuss,发现大家的解法实现上看起来都差不多,用递归,递归的条件以及参数的更新都类似。然后我看了他们的解释,才意识到原来自己的实现暗合了回溯的思想,我做的时候就只是当作生成一棵二叉树来做了。。。没系统学过算法的孩子想题目时就是显得很幼稚/(ㄒoㄒ)/~~
由于我的代码跟其他大牛的代码类似,就只贴出我的代码。
class Solution {
private:
vector<string> result;
int number;
public:
vector<string> generateParenthesis(int n) {
number = n;
generator("(", 1, 0);
return result;
}
void generator(string s, int left, int right) {
if (right == number)
result.push_back(s);
if (left > right)
generator(s + ")", left, right + 1);
if (left < number)
generator(s + "(", left + 1, right);
}
};
这道题不难,但是我一开始把时间浪费在了想通过插入法来解题,即将左右括号按一定的规则不断插入到字符串中,然而这种想法太复杂了,没做出来,就换一个思路,逐个位置去填,然后就联想到了生成树的算法,结果几分钟就做出来了,看来找到正确的方向真的很重要呀~
算是轻松地填了这个坑,继续加油!明天从填坑之路上再次出发~