tema:
soportes. Diseñe un algoritmo para imprimir todas las combinaciones legales (por ejemplo, correspondencia uno a uno abierta y cerrada) de n pares de paréntesis.
Nota: El conjunto de soluciones no puede contener subconjuntos duplicados.
Por ejemplo, dado n = 3, el resultado generado es:
[
"((()))",
"(() ())",
"(()) ()",
"() (())",
"() () ()"
]
fuente:
Pregunta de la entrevista 08.09. Paréntesis
Ideas para resolver problemas: retroceder
Defina dos variables izquierda y derecha, la izquierda registra el número de '(', la derecha registra el número de ')'.
- Condición de terminación recursiva: el paréntesis izquierdo debe terminarse primero, por lo que termina cuando termina el paréntesis derecho
- Condición de llamada recursiva: de acuerdo con la situación actual de izquierda y derecha, determine la posible situación del siguiente carácter
public:
vector<string> result;
string path;
vector<string> generateParenthesis(int n) {
back(n, 0, 0);
return result;
}
void back(int n, int left, int right) {
if (right == n) {
// 返回结果
result.push_back(path);
return;
}
// 找出所有可能情况
char cand[2];
int sz = 0;
if (left < n) {
cand[sz++] = '(';
}
if (left > right) {
cand[sz++] = ')';
}
// 处理每种可能情况
for (int i = 0; i < sz; i++) {
path.push_back(cand[i]);
if (cand[i] == '(')
back(n, left+1, right);
else
back(n, left, right+1);
path.resize(path.size() - 1);
}
}
};
Otra forma de pensar, el código es más conciso, como sigue:
Dos variables, izquierda registra el número restante de paréntesis izquierdos y derecha registra el número restante de paréntesis derechos. Hay 2 situaciones posibles:
- Paréntesis izquierdo, manipular cuando quede
- El paréntesis derecho, cuando el paréntesis izquierdo es izquierdo, y el paréntesis izquierdo es pequeño.
class Solution {
public:
vector<string> result;
string path;
vector<string> generateParenthesis(int n) {
back(n, n);
return result;
}
// left记录左括号剩余数量,right记录右括号剩余数量
void back(int left, int right) {
if (left == 0 && right == 0) {
result.push_back(path);
return;
}
// 无非2种可能情况
if (left > 0) {
// 情况1
path.push_back('(');
back(left-1, right);
path.resize(path.size() - 1);
}
if (left < right && right > 0) {
// 情况2
path.push_back(')');
back(left, right - 1);
path.resize(path.size() - 1);
}
}
};