序文:前回、単純なブラケット生成を行いましたが、前回のバックトラッキング問題を実行するときに間違いを見つけただけです。バックトラッキングは再帰とは異なります。現在の状態を保存するために、バックトラッキングメソッドにはグローバル変数があります。メソッドが完了すると、 、前の状態に戻ります。
数値nは括弧の生成の対数を表します。括弧の可能なすべての効果的な組み合わせを生成する関数を設計してください。
例:
输入:n = 3
输出:[
"((()))"、
"(()())"、
"(())()"、
"()(())"、
"()()( ) "
]
この質問はそれほど難しくありません。私は最終的な状態を判断するためにペアを使用しました。最終的な状態は3ペアの文字列ですが、実際にはこの条件は他のより良い条件に置き換えることができ、次のようなハスペアのスペースも節約できます。文字列の長さを判断したり、左角括弧と右角括弧の数がnになったかどうかを判断したりします。
同時に、現在の文字列を格納するグローバル変数sを開発するというバックトラックのアイデアを使用しましたが、前のノードの状態に戻るので、この問題では、文字列の最後の文字を削除することによって戻る必要があります。
この画像を使用して、次のことを理解できます。
州の撤退は、実際にはDからBに戻るプロセスです
具体的な実装コードは次のとおりです。
class Solution {
string s ="";
public:
vector<string> generateParenthesis(int n) {
char symbol[2] = {'(',')'};
vector<string> result;
if(n == 0){
result.push_back("");
return result;
}else{
genSymbol(result, '(', 1, 0, 0, n);
genSymbol(result, ')', 0, 1, 0, n);
return result;
}
}
void genSymbol(vector<string> &result, char symbol, int leftB, int rightB, int hasPair, int n ){
if(hasPair == n){
s += ')';
result.push_back(s);
s.pop_back();
return;
}else{
s += symbol;
if(leftB < n){
// cout << s << " " << hasPair<< " "<< leftB<<" " << rightB<< endl;
genSymbol(result, '(', leftB+1, rightB, hasPair, n);
}
if(leftB > rightB){
// cout << s << " " << hasPair+1<< " "<< leftB<<" " << rightB<< endl;
genSymbol(result, ')', leftB, rightB+1, hasPair+1, n);
}
s.pop_back();
}
}
};
実際、メモリ消費にはまだ最適化の余地があります〜