【回溯】【leetcode】长度为 n 的开心字符串中字典序第 k 小的字符串

题目:

一个 「开心字符串」定义为:

  • 仅包含小写字母 ['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);
        }
    }
};

猜你喜欢

转载自blog.csdn.net/hbuxiaoshe/article/details/114899749