题目:
一个 「开心字符串」定义为:
- 仅包含小写字母 ['a', 'b', 'c'].
- 对所有在 1 到 s.length - 1 之间的 i ,满足 s[i] != s[i + 1] (字符串的下标从 1 开始)。
比方说,字符串 "abc","ac","b" 和 "abcbabcbcb" 都是开心字符串,但是 "aa","baa" 和 "ababbc" 都不是开心字符串。
给你两个整数 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 个字符串为 "cab"
如果k=13,返回""。
来源:
1415. 长度为 n 的开心字符串中字典序第 k 小的字符串
解题思路:回溯
- 递归终止条件:path长度等于n
- 结果条件:递归终止时,第k个,增加一个计数变量cnt。
- 剪枝:结果条件满足时应退出所有的递归,即计数>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);
}
}
};