您的位置:首页 > 编程语言 > Go语言

[LeetCode] Generate Parentheses 解题报告

2017-03-13 20:26 357 查看
[题目]

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 = 3,解集是:

[

“((()))”,

“(()())”,

“(())()”,

“()(())”,

“()()()”

]

[解题思路]

有两种想法,一种是先枚举出用’(‘或’)’构成长度为2n的字符串的所有可能,一共有22n,然后对于每一种可能,去判断一下是否合法,然后获得所有合法的可能。另一种自然的想法是使用递归,我采用的是递归的解法。

关于什么是递归,为什么会想到使用递归,这里就不细讲了。因为递归这种思想,对初学者而言有点难,对已经入门的却又很自然。建议初学者单步调试一下递归的代码,具体看一下执行过程中那些变量是什么样的,这样或许容易理解递归究竟是怎么递归下去的,又是怎么回溯上来的。

我这里设计的递归函数如下:

void generateParenthesisRecursively(vector<string>& res, int leftQuote, int rightQuote, int n, string s);


res是最后的结果,作为引用传入,也可以设成一个全局变量。

leftQuote是当前字符串s中已有的左括号个数。

rightQuote是当前字符串s中已有的右括号个数。

n是题目中输入的n,也可以改成全局变量。

s是当前递归到的字符串。

递归其实就是有条理地在进行状态搜索。

先判断一下当前的字符串s是否是一个合法的括号组合。

如果当前s中leftQuote=rightQuote=n,那么说明当前的s已经是一个合法的括号组合,可以将它加入res。而且在s的基础上再继续添加任何字符都不可能构成其他的合法字符,所以不需要继续递归下去。这是递归的终结点。

if (leftQuote == rightQuote && leftQuote == n) {
res.push_back(s);
return;
}


如果s还不是一个合法的括号组合,那么可以在s的基础上扩展一个’(‘或’)’。

只要leftQuote<n,就可以扩展一个’(‘,以s+’(‘为前缀的字符串可能成为一个合法括号匹配,因此需要继续递归。

if (leftQuote < n)
generateParenthesisRecursively(res, leftQuote + 1, rightQuote, n, s + "(");
}


如果leftQuote>rightQuote,就可以扩展一个’)’,以s+’)’为前缀的字符串可能成为一个合法括号匹配,因此需要继续递归。

if (leftQuote > rightQuote)
generateParenthesisRecursively(res, leftQuote, rightQuote + 1, n, s + ")");


这样的一个递归,不会有漏掉没有搜索的状态,因为它保证了所有可能构成合法括号组合的前缀s都会被搜索到。同时,它又不会永无止境地递归下去,因为leftQuote<n和leftQuote>rightQuote两个继续递归的条件保证了最终一定会达到leftQuote=rightQuote=n,而这是一个终结状态。

补充一点,这里实际上(leftQuote, rightQuote, s)构成了递归的状态,s控制了结果,leftQuote和rightQuote控制了递归的方向和递归的停止。实际上,用这三个变量来表示状态,是有多余的,只是为了便于理解。

[C++代码]

class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<string> result;

generateParenthesisRecursively(result, 0, 0, n, "");

return result;
}
void generateParenthesisRecursively(vector<string>& res, int leftQuote, int rightQuote, int n, string s) {
if (leftQuote == rightQuote && leftQuote == n) { res.push_back(s); return; }

if (leftQuote < n)
generateParenthesisRecursively(res, leftQuote + 1, rightQuote, n, s + "(");

if (leftQuote > rightQuote) generateParenthesisRecursively(res, leftQuote, rightQuote + 1, n, s + ")");
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode algorithm