【问题标题】:Editing recursive algorithm: passing array instead of string as an argument to save results instead of printing编辑递归算法:传递数组而不是字符串作为参数来保存结果而不是打印
【发布时间】:2020-02-21 16:18:23
【问题描述】:

我有这段代码可以从长度为 k 的数组中找到 n 个组合:

class Util
{
    // Function to print all distinct combinations of length k
    public static void recur(int[] A, String out, int n, int k)
    {
        // invalid input
        if (k > n) {
            return;
        }

        // base case: combination size is k
        if (k == 0) {
            System.out.println(out);
            return;
        }

        // start from next index till first index
        for (int i = n - 1; i >= 0; i--)
        {
            // add current element A[i] to output and recur for next index
            // (i-1) with one less element (k-1)
            recur(A, (A[i]) + " " + out, i, k - 1);
        }
    }

    public static void main(String[] args)
    {
        int[] A = {0, 1, 2, 3 };
        int k = 2;
        // process elements from right to left
        recur(A, "", A.length, k);
    }
}

它工作正常,它的主要方法打印

2 3 
1 3 
0 3 
1 2 
0 2 
0 1 

但是我想将这些组合保存在一个列表中:List<int[]>List<List<Integer>>。我试图编辑算法:

public static void recur(int[] A, List<Integer> out, int n, int k)
    {
        // invalid input
        if (k > n) {
            return;
        }

        // base case: combination size is k
        if (k == 0) {
            System.out.println(out);
            return;
        }

        // start from next index till first index
        for (int i = n - 1; i >= 0; i--)
        {
            out.add(A[i]);
            // add current element A[i] to output and recur for next index
            // (i-1) with one less element (k-1)
            recur(A, out, i, k - 1);
        }
    }

但它没有按预期工作:它会打印

[3, 2]
[3, 2, 1]
[3, 2, 1, 0]
[3, 2, 1, 0, 2, 1]
[3, 2, 1, 0, 2, 1, 0]
[3, 2, 1, 0, 2, 1, 0, 1, 0]

对于这个主要方法:

public static void main(String[] args)
        {
            int[] A = {0, 1, 2, 3 };
            int k = 2;
            recur(A, new ArrayList<>(), A.length, k);
        }

【问题讨论】:

  • 主要区别(这将提示您找到问题)是您的第一个版本在每个递归调用中传递一个新字符串,但您的第二个版本修改现有列表并传递相同的列表每次调用中的实例。

标签: java algorithm recursion combinations


【解决方案1】:

String out 的第一种情况有效,因为 String 是不可变的,因此您可以通过它而不会损害原始内容。

ArrayList 的第二种情况不起作用,因为您传递了 reference,并且当您修改“reference”的内容时,您会修改原始内容。

【讨论】:

    【解决方案2】:

    您在典型的回溯中缺少 Choose - Explore - Unchoose 方法的 Unchoose 部分。

    您的选择部分是out.add(A[i])

    您的探索部分是recur(A, out, i, k - 1)

    您的 Unchoose 部分应该是删除您最后选择的元素,即列表的最后一个元素:out.remove(out.size()-1)

    【讨论】:

      猜你喜欢
      • 2021-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-01
      相关资源
      最近更新 更多