Arraylist的递归更新不正确

时间:2019-02-22 18:24:35

标签: java recursion

下面是我的函数,它给出给定数组中的元素求和到特定目标的所有可能性。我可以打印列表,但是结果列表没有更新。

public List<List<Integer>> helper(List<List<Integer>> res, int[] c, int l, int h, int target, List<Integer> temp){
        if(target == 0){
            res.add(temp);
            System.out.println(temp);
            return res;
        }
        if(target < c[l]){
            return res; 
        }
        for(int i = l; i <=h; i++){
            temp.add(c[i]);
            res = helper(res, c,i,h,target-c[i], temp);
            temp.remove(temp.size()-1);
        }
        return res;
    }

res是最后一个空数组列表的数组列表,但是第5行正确打印了临时数组列表。

该函数的调用如下。

List<List<Integer>> res = new ArrayList<List<Integer>>();
List<Integer> temp = new ArrayList<Integer>();
res = helper(res,candidates, 0, candidates.length-1, target, temp);

示例: 给定数组= [1,2,3],目标= 6

标准输出:

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

res is [[],[],[],[],[],[],[]]

2 个答案:

答案 0 :(得分:1)

这是针对按值传递问题的标准通过引用

您要将temp的引用添加到res对象,因此,只要temp的值发生更改(在程序中的for loop内),它就会更改值res中的一个实例的最后一个元素,因此当从temp中删除所有元素时,列表变为空,然后将res中的所有值更改为空列表。 / p>

先更改您的 helper方法(如有条件),如下所示,它应该可以工作:

if(target == 0){
  ArrayList<Integer> copy = new ArrayList<>(temp);
  res.add(copy);
  return res;
}

说明

我们没有创建对temp的引用res,而是创建了temp的简单副本,然后将其添加到res

这可以防止用新的对象值覆盖值。

答案 1 :(得分:1)

每次将温度添加到res中。因此,每次您向temp列表添加相同的res引用时。最后temp将是一个空列表,因此res中的所有值都将为空,因为它们指向相同的temp引用。 如果通过新的临时列表,则可以解决此问题。

public static List<List<Integer>> helper(List<List<Integer>> res, int[] c, int l, int h, int target, List<Integer> temp){
        if(target == 0){
            res.add(temp);
            System.out.println(temp);
            return res;
        }
        if(target < c[l]){
            return res; 
        }
        for(int i = l; i <=h; i++){
            temp.add(c[i]);
            res = helper(res, c,i,h,target-c[i], new ArrayList<Integer>(temp));
            temp.remove(temp.size()-1);
        }
        return res;
    }

enter image description here