トピック:
「ハッピーストリング」は次のように定義されます。
- 小文字['a'、 'b'、 'c']のみを含みます。
- 1からs.length-1までのすべてのiについて、s [i]!= s [i + 1]を満たします(文字列の添え字は1から始まります)。
たとえば、文字列「abc」、「ac」、「b」、「abcbabcbcb」はすべて幸せな文字列ですが、「aa」、「baa」、「ababbc」は幸せな文字列ではありません。
2つの整数nとkが与えられた場合、長さnのすべての幸せな文字列を辞書式順序で並べ替える必要があります。
ソート後、k番目の幸せな文字列を返してください。長さがnの幸せな文字列がk個未満の場合は、空の文字列を返してください。
促す:
1 <= n <= 10
1 <= k <= 100
例3:
入力:n = 3、k = 9
出力: "cab"
説明:長さ3の合計12個のハッピーストリングがあります["aba"、 "abc"、 "aca"、 "acb"、 "bab"、 "bac "、" bca "、" bcb "、" cab "、" cac "、" cba "、" cbc "]。9番目の文字列は「タクシー」です
k = 13の場合、「」を返します。
ソース:
1415.長さnの幸せな文字列の中で辞書式順序でk番目に小さい文字列
問題解決のアイデア:バックトラック
- 再帰的終了条件:パスの長さがnに等しい
- 結果条件:再帰が終了すると、k番目の再帰はカウント変数cntを追加します。
- 枝刈り:結果条件が満たされた場合、つまり、count> kの場合、すべての再帰を終了する必要があります。
- 再帰パラメータ:現在の文字が渡され、再帰中に着信文字に応じて次の可能な文字を決定できます。次の可能な文字は文字セットを形成し、文字列で表されます。
class Solution {
public:
string result;
string path;
int cnt;
string getHappyString(int n, int k) {
cnt = 0;
result.clear();
back(0, n, k);
return result;
}
void back(char prev, int n, int k) {
if (n == 0) { // 终止
cnt++;
if (cnt == k) result = path; // 结果满足
return;
}
string s("abc");
if (prev == 'a') s = "bc";
else if (prev == 'b') s = "ac";
else if (prev == 'c') s = "ab";
for (int i = 0; i < s.size(); i++) {
if (cnt > k) break; // 剪枝
path.push_back(s[i]);
back(s[i], n - 1, k);
path.resize(path.size() - 1);
}
}
};