[Leetcode] Generate Parentheses
Generate Parentheses 题解
题目来源:https://leetcode.com/problems/generate-parentheses/description/
Description
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
Example
For example, given n = 3, a solution set is:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
Solution
class Solution {
private:
void addPare(vector<string>& res, string str, int leftNeed, int rightNeed) {
if (leftNeed == 0 && rightNeed == 0) {
res.push_back(str);
} else {
if (leftNeed > 0)
addPare(res, str + '(', leftNeed - 1, rightNeed + 1);
if (rightNeed > 0) {
addPare(res, str + ')', leftNeed, rightNeed - 1);
}
}
}
public:
vector<string> generateParenthesis(int n) {
vector<string> res;
if (n <= 0)
return res;
addPare(res, "", n, 0);
return res;
}
};
解题描述
这道题题意是,求出包含n对括号的合法(合法即满足编译要求)括号串。上面给出的做法是递归的方法:
- 初始状态下,左括号需要的数目
leftNeed = n
和右括号需要的数目rightNeed = 0
- 每次添加上左括号则
leftNeed
要自减,但是rightNeed
要自增(左右匹配) - 每次添加上右括号则
rightNeed
要自减 leftNeed
和rightNeed
均为0的时候说明括号串已经生成,可以添加到结果
评论区还给出了这道题的迭代方法,主要的思想是DP:n对括号的情况,是由n - 1,n - 2,... ,1对括号的情况组合起来的。所以可以从1开始一直往n进行递推:
class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<vector<string> > dp(n + 1, vector<string>());
dp[0] = vector<string>{""};
int i, j;
for (i = 1; i <= n; i++) {
for (j = 0; j < i; j++)
for (auto first : dp[j])
for (auto second : dp[i - 1 - j]) {
auto temp = '(' + first + ')' + second;
dp[i].push_back(temp);
}
}
return dp[n];
}
};
算法的关键在于temp = '(' + first + ')' + second
first
和second
是n之前的2中互补的情况,即括号对数之和为n - 1,再加上一对括号就是n对括号的情况- 而
first
的括号对数是升序,second
的括号对数是降序,这样就能遍历所有的组合情况。