题目:Generate Parentheses
原题链接:https://leetcode.com/problems/generate-parentheses/
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;
那么一共有下面 5 种组合:
[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
首先,要保证组合的合法性,即不能出现类似 “())(”这种不合法的情况。可以每次先添上一个左括号” ( “, 然后记录提醒自己后面要补上一个右括号” ) “。
由于一共有 n 对括号需要组合,换言之字符串有 2n 个位置让我们选择是放” ( “还是” ) “。可以采用回溯的思想,先一直放” ( “,同时累计还需要放的” ) “个数,然后等到这样字符串的 0 到 n - 1 位置就都是” ( “, 然后n - 1 到2n - 1都是” ) “,然后在回溯到第n - 2个位置,这次我们把这个位置上不放 ” ( “,而是先放” )”,然后接着对n - 1到 2n - 1的位置进行选择,这时我们只剩下一个” ( “和n - 1个 ” ) “,按照先放” ( “的规则,先放” ( “再放剩下的n - 1个” ) “;然后回溯到n - 3的位置,这个位置放置” ) “, 后面n - 2到2n - 1的位置有2个” ( “和n - 1个” ) “可以选择,再按照规则防止,依次回溯,一直到第二个位置改放” ) “截止。
具体的做法,用left和right来分别记录还需要放的” ( ” 和” ) “的个数,初始left为 n ,right为0,这是因为right只有在已经放了” ( “的情况下才增加计数。
当left 大于0的时候,放置一个” ( “,left减一并且right的计数加 1;
当right大于0的时候,放置一个” ) “,right减一;
当left和right都为0的时候,组合完毕,这个字符串压入数组。
代码如下:
class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<string> ans;
insert(ans, "", n, 0);
return ans;
}
void insert(vector<string>& v, string s, int left, int right) {
if(!left && !right) {
v.push_back(s);
return;
}
if(left > 0) insert(v, s + '(', left - 1, right + 1);
if(right > 0) insert(v, s + ')', left, right - 1);
}
};