【问题标题】:Backtracking with recursion. Why is the code working使用递归回溯。为什么代码有效
【发布时间】:2022-01-20 03:11:16
【问题描述】:

你能帮我理解下面的代码sn-p吗?注释说它正在通过回溯进行字符串排列,但我就是不明白。我不明白嵌套的 for 循环在做什么。我试图用“Cat”跟随代码。不是排列集有吗?

public static Set<String> getPermutations(String inputString) {
        if(inputString.length() <= 1) {
            return new HashSet<>(Collections.singletonList(inputString));
        }
        String allCharsExceptLast = inputString.substring(0, inputString.length()-1);
        char lastChar = inputString.charAt(inputString.length()-1);

        Set<String> permutationsOfAllCharsExceptLast = getPermutations(allCharsExceptLast);

        Set<String> permutations = new HashSet<>();
        for(String permutationOfAllCharsExceptLast: permutationsOfAllCharsExceptLast) {
            for(int position = 0; position <= allCharsExceptLast.length(); position++) {
                String permutation = permutationOfAllCharsExceptLast.substring(0, position) + lastChar +
                        permutationOfAllCharsExceptLast.substring(position);
                permutations.add(permutation);
            }
        }

        return permutations;
    }

}

【问题讨论】:

    标签: java algorithm data-structures backtracking


    【解决方案1】:

    算法的工作原理如下:

    1. 基本情况:当字符串仅包含一个字符时,则返回仅包含该字符串的集合:这是唯一可能的排列。

    2. 解决少一个字符的问题:获取缺少原始最后一个字符的较短字符串的所有排列。

    3. 对于此递归调用返回的集合中的每个排列,请执行以下操作:

      • 在这个排列中选择每个可能的索引,我们可以在其中插入一个字符,即 0 到较短字符串的长度(包括):

        • 在此排列中,在给定索引处:插入排除的字符,从而构造一个包含现在所有字符的排列。

    因此,第 3 步需要两个嵌套循环:一个用于获取较短字符串的每个排列,另一个用于选择将排除字符插入该排列的索引。

    示例:

    输入:

    "abcd"
    

    在第 2 步中,我们查看较短的字符串“abc”,并相信该函数会为其生成正确的结果(归纳推理),即集合:

    { "abc", "acb", "bac", "bca", "cab", "cba" }
    

    现在我们进入第 3 步。外部循环遍历这个集合。内部循环选择 0 到 3(包括在内)之间的索引。所以让我们把它放在一个表格中:

    shorter permutation index at which to insert "d" resulting permutation
    "abc" 0 "dabc"
    "abc" 1 "adbc"
    "abc" 2 "abdc"
    "abc" 3 "abcd"
    "acb" 0 "dacb"
    "acb" 1 "adcb"
    "acb" 2 "acdb"
    "acb" 3 "acbd"
    "bac" 0 "dbac"
    "bac" 1 "bdac"
    "bac" 2 "badc"
    "bac" 3 "bacd"
    "bca" 0 "dbca"
    "bca" 1 "bdca"
    "bca" 2 "bcda"
    "bca" 3 "bcad"
    "cab" 0 "dcab"
    "cab" 1 "cdab"
    "cab" 2 "cadb"
    "cab" 3 "cabd"
    "cba" 0 "dcba"
    "cba" 1 "cdba"
    "cba" 2 "cbda"
    "cba" 3 "cbad"

    然后返回这个结果集。

    希望这可以澄清它。

    【讨论】:

    • 非常感谢先生
    猜你喜欢
    • 2013-01-29
    • 2019-10-11
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多