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

一、题目描述

A happy string is a string that: consists only of letters of the set [‘a’, ‘b’, ‘c’].
s[i] != s[i + 1] for all values of i from 1 to s.length - 1 (string is 1-indexed).
For example, strings “abc”, “ac”, “b” and “abcbabcbcb” are all happy strings and strings “aa”, “baa” and “ababbc” are not happy strings.

Given two integers n and k, consider a list of all happy strings of length n sorted in lexicographical order.

Return the kth string of this list or return an empty string if there are less than k happy strings of length n.

Input: n = 3, k = 9
Output: "cab"
Explanation: There are 12 different happy string of length 3 
["aba", "abc", "aca", "acb", "bab", "bac", "bca", "bcb", "cab", "cac", "cba", "cbc"]. 
You will find the 9th string = "cab"

二、题解

方法一:回溯

  • aba
    abc
    aca

每次递归之前都判断当前可用字符是否等于上一次的字符:

  • 不相同,则可加到字符串的末尾。
  • 否则,跳过,继续枚举下一个字符。

本质上就是全排列的拓展应用呀…

未知错误:不知道是哪里有错,求出来的字符串个数总是少于 k 个。

int n;
List<String> list;
StringBuilder sb;
private void dfs(char pre) {
    if (sb.length() == n) {
        System.out.println(sb.toString());
        list.add(new String(sb.toString()));
        return;
    }
    for (char c = 'a'; c <= 'c'; c++) {
        if (c == pre && sb.length() > 0)
            continue;
        sb.append(c);
        dfs(c);
        sb.deleteCharAt(sb.length()-1);
    }
}
public String getHappyString(int n, int k) {	//返回所有长度为n的第k个happy字符
    this.n = n;
    list = new ArrayList<>();
    sb = new StringBuilder("a");
    dfs('a');
    if (list.size() < k)
        return "";
    //Collections.sort(list);
    return list.get(k-1);
}

修正代码…

class Solution {
    StringBuilder sb;
    List<String> all;
    void dfs(int n, String s) {
        if (n == 0) {
            all.add(s);
            return;
        }
        for (char c = 'a'; c <= 'c'; c++) {
            if (s.length() > 0 && c == s.charAt(s.length()-1))
                continue;
            dfs(n-1, s+c);
        }
    }
    public String getHappyString(int n, int k) {
        all = new ArrayList<>();
        dfs(n, "");
        if (all.size() < k)
            return "";
        return all.get(k-1);
    }
}

复杂度分析

  • 时间复杂度: O ( 2 n ) O(2^n) O(2n)
  • 空间复杂度: O ( 2 n ) O(2^n) O(2n)

方法二:优化

因为回溯出来的字符串都是字典序的,所以我们只需用 String res 来记录当 idx == k 时的字符串即可。


你可能感兴趣的:(#,【回溯】,#,字符串)