[Backtracking] [leetcode] The k-th smallest string in lexicographical order among happy strings of length n

topic:

A "happy string" is defined as:

  • Contain only lowercase letters ['a','b','c'].
  • For all i between 1 and s.length-1, satisfy s[i] != s[i + 1] (the subscript of the string starts from 1).

For example, the strings "abc", "ac", "b" and "abcbabcbcb" are all happy strings, but "aa", "baa" and "ababbc" are not happy strings.

Given two integers n and k, you need to sort all happy strings of length n in lexicographic order.

Please return the k-th happy string after sorting. If there are fewer than k happy strings of length n, then please return an empty string.

prompt:

  • 1 <= n <= 10
  • 1 <= k <= 100

Example 3:

Input: n = 3, k = 9
Output: "cab"
Explanation: There are a total of 12 happy strings of length 3 ["aba", "abc", "aca", "acb", "bab", "bac ", "bca", "bcb", "cab", "cac", "cba", "cbc"]. The 9th string is "cab"

If k=13, return "".

source:

1415. The k-th smallest string in lexicographical order among happy strings of length n

Problem-solving ideas: backtracking

  • Recursive termination condition: path length is equal to n
  • Result condition: When the recursion terminates, the k-th one adds a count variable cnt.
  • Pruning: When the result condition is met, all recursion should be exited, that is, when the count>k.
  • Recursive parameters: The current character will be passed in, and the next possible character can be determined according to the incoming character during recursion. The next possible character forms a character set and is represented by a string.
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);
        }
    }
};

 

Guess you like

Origin blog.csdn.net/hbuxiaoshe/article/details/114899749