• res.add(new ArrayList<>(path))和res.add(path)的区别


    一.问题描述

    在链表path里面添加值,之后把path链表添加到res链表中,自己做的时候使用res.add(path),结果发现出现解答错误。

    题目链接113. 路径总和 II - 力扣(LeetCode)

    代码如下

    class Solution {
        public List> pathSum(TreeNode root, int targetSum) {
            List> res = new ArrayList<>();
            if(root==null){
                return res;
            }
            List path = new ArrayList<>();
            dfs(root,targetSum,res,path);
            return res;
        }
            public void dfs(TreeNode root,int targetSum,List> res,List path){
                path.add(root.val);
                if(root.left==null&&root.right==null){
                    if(targetSum==root.val){
                        res.add(new ArrayList<>(path));
                    }
                    return;
                }
                if(root.left!=null){
                    dfs(root.left,targetSum-root.val,res,path);
                    path.remove(path.size()-1);
                }
                  if(root.right!=null){
                    dfs(root.right,targetSum-root.val,res,path);
                    path.remove(path.size()-1);
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    共同点:
      都是向res这个ArrayList中填加了一个名为path的链表

    不同点:

    • res.add(new ArrayList(path)):开辟一个独立地址,地址中存放的内容为path链表,后续path的变化不会影响到res

    • res.add(path):将res尾部指向了path地址,后续path内容的变化会导致res的变化。

    总结:被压入栈的变量也会因为后续该变量的改变而改变,引用内存的引用也会随着实例对象的改变而改变。

    二.例子测试

    期望输出是

    []
    [[a, b, c]]
    [[a, b, c], [a, b, c, d]]

    1.用res.add(path)
    public class Solution {
        public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();
            list.add("a");
            list.add("b");
            list.add("c");
            List<List<String>> result = new ArrayList<>();
            //1.输出为空
            System.out.println(result);
            //2.第一次添加,res值应该为abc
            result.add(list);
            System.out.println(result);
            //3.第二次添加,res值按照自己的猜想应该是abc,abcd
            list.add("d");
            result.add(list);
            System.out.println(result);
            System.out.println("使用res.add(path)");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    image-20221105121632881

    与期望输出不一样

    原因如下:因为被压入栈的变量也会因为后续该变量的改变而改变,指向的是同一个地址,所以之前的也改变了。

    2.用res.add(new ArrayList(path))
    public class Solution {
        public static void main(String[] args) {
            ArrayList list = new ArrayList<>();
            list.add("a");
            list.add("b");
            list.add("c");
            List> result = new ArrayList<>();
            //1.输出为空
            System.out.println(result);
            //2.第一次添加,res值应该为abc
            result.add(new ArrayList<>(list));
            System.out.println(result);
            //3.第二次添加,res值按照自己的猜想应该是abc,abcd
            list.add("d");
            result.add(new ArrayList<>(list));
            System.out.println(result);
            System.out.println("使用res.add(new ArrayList(path))");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    image-20221105122135124

    与期望输出一样

    原因如下:new ArrayList<>(list)是又开辟一个独立地址,地址中存放的内容为path链表,后续path的变化不会影响到res,所以每次new都会开辟一个新的地址来存放path链表。

  • 相关阅读:
    ⑤、企业快速开发平台Spring Cloud之HTML <head>
    Oracle 19c RAC OS的准备检查阶段
    蓝桥杯中级题目之组合(c++)
    JPEG公布智能图像编码提案结果,火山引擎排名主观质量评测第一
    LPL Ban/Pick 选人阶段的遮罩效果是如何实现的?
    java构造方法使用
    U2-Net——U-Net中套U-Net,套娃式的分割模型
    day4作业
    Unity与安卓⭐三、Unity报错合集
    为什么会过拟合?判断依据?训练集验证集和测试集之间的关系?
  • 原文地址:https://blog.csdn.net/weixin_54040016/article/details/127707584