最近在写java全排列的题目时,

List<List<Integer>> result=new ArrayList();最终所有排列的集合
List<Integer> curlist=new ArrayList();动态的集合表示当前路径

最后出现了列表全空的bug,代码如下:

   void findpermution(int len,int[] nums,int layer,List<Integer> curlist, boolean[] used,List<List<Integer>> result){
        if(layer==nums.length){
            result.add(curlist);
            return;
        }
        for(int i=0;i<nums.length;i++)
        { 
            if(!used[i]){
                curlist.add(nums[i]);
                used[i]=true;
                findpermution(len,nums,layer+1,curlist,used,result);
                used[i]=false;
                curlist.remove(curlist.size()-1);
            }
        }
    }

搜索了一下才发现是 Arraylist.add(curlist) 这里的问题。Arraylist.add() 这个方法传递的是对象引用,每次的add只是将引用地址放入集合中,而没有创建新的对象(如果对于对象与对象引用有不明白的地方需要巩固下);从表面上来解释就是每一次想要添加的 list 都会覆盖原来的 list ,实际上是虽然对象在变,但引用不变,所以最终的运行结果是最后添加的对象变化(在全排列这题当中是最后回溯到path大小为0)。

解决方法:

浅拷贝

每次想要添加的list。

代码:

     if(layer==nums.length){
            result.add(new ArrayList<>(curlist));
            return;
        }

原理:相比较对象引用,浅拷贝构造了另一个引用。因此每次添加的都是当前改变的list。



版权声明:本文为qq_43606914原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_43606914/article/details/105801587