最近在写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 版权协议,转载请附上原文出处链接和本声明。