Java 编辑递归算法:将数组而不是字符串作为参数传递,以保存结果而不是打印

Java 编辑递归算法:将数组而不是字符串作为参数传递,以保存结果而不是打印,java,algorithm,recursion,combinations,Java,Algorithm,Recursion,Combinations,我有以下代码,用于从长度为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; }

我有以下代码,用于从长度为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
list
。我试图编辑算法:

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);
        }
    }
对于此主要方法:

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

第一个使用字符串out的案例是有效的,因为字符串是不可变的,所以您可以传递它而不损害原始字符串


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

第一种情况是字符串out起作用,因为字符串是不可变的,所以您可以传递它而不损害原始内容

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

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

您选择的部分是
out。添加(A[i])

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

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

在典型的回溯中,您缺少Choose-Explore-Unchoose方法的取消选择部分

您选择的部分是
out。添加(A[i])

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

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

主要区别(这将提示您找到问题)是第一个版本在每次递归调用中传递一个新字符串,但是您的第二个版本会修改现有列表,并在每次调用中传递相同的列表实例。主要区别(这将为您找到问题提供提示)是,您的第一个版本会在每次递归调用中传递一个新字符串,而您的第二个版本会修改现有列表,并在每次调用中传递相同的列表实例。
public static void main(String[] args)
        {
            int[] A = {0, 1, 2, 3 };
            int k = 2;
            recur(A, new ArrayList<>(), A.length, k);
        }