【问题标题】:Arraylist is not getting updated in recursion correctlyArraylist 没有在递归中正确更新
【发布时间】:2019-02-23 05:47:54
【问题描述】:

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

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 [[],[],[],[],[],[],[]]

【问题讨论】:

  • 你的输入是什么,你的调试结果是什么?
  • 更新了输入和结果

标签: java recursion


【解决方案1】:

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

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

如果条件如下更改您的辅助方法,它应该可以工作:

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

说明

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

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

【讨论】:

    【解决方案2】:

    每次您将 temp 添加到 res 时。所以每次你添加相同的temp 引用res 列表。最后temp 将是一个空列表,因此res 中的所有值都将为空,因为它们指向相同的temp 引用。 如果您为 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;
        }
    

    【讨论】:

    • 什么叫浅拷贝?添加对列表的引用肯定不是 - stackoverflow.com/q/184710/85421
    • 其实不是浅拷贝。它只是持有温度的参考。检查更新的答案。
    • @CarlosHeuberger 我正在考虑其他一些无效的情况。所以我更正了答案。
    猜你喜欢
    • 1970-01-01
    • 2020-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多