一道典型的回溯,可以使用以下2种方法:
- 生成所有的情况,判断每种情况是否符合题意
vector<string> generateParenthesis(int n) {
vector<string> res;
string s;
generateAllParenthesis(n, s, res);
return res;
}
void generateAllParenthesis(int n, string s, vector<string> &res) {
if (s.size() == 2 * n) {
if (isValid(s)) {
res.push_back(s);
}
} else {
generateAllParenthesis(n, s + "(", res);
generateAllParenthesis(n, s + ")", res);
}
}
bool isValid(string s) {
int cnt = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == '(') cnt++;
else if (s[i] == ')') cnt--;
if (cnt < 0) return false;
}
return cnt == 0;
}
- 限定生成括号的类型,必须保证左括号的要和右括号一一匹配
class Solution {
public:
vector<string> generateParenthesis(int n) {
vector<string> res;
backTrack(n, 0, 0, "", res);
return res;
}
void backTrack(int n, int left, int right, string s, vector<string> &res) {
if (left + right == 2 * n) res.push_back(s);
if (left < n) {
backTrack(n, left + 1, right, s + "(", res);
}
if (right < left) {
backTrack(n, left, right + 1, s + ")", res);
}
}
};