List.add方法传入的是地址(引用)而不是值
在刷LeetCode时,碰到一个List.add方法的问题
题目如下:https://leetcode-cn.com/problems/combinations/
正确结果应该是:
[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],]
1.问题代码如下
public class No77_combinations { public static void main(String[] args) { List<List<Integer>> lists; lists = new Solution77().combine(4, 2); System.out.println(lists);//问题:最终返回结果为[[], [], [], [], [], []] } } class Solution77 { public List<List<Integer>> combine(int n, int k) { List<List<Integer>> lists = new ArrayList<>(); List<Integer> list = new ArrayList<>(); dfs(n, k, 0, list,lists); return lists; } private List<List<Integer>> dfs(int n, int k, int index, List<Integer> list,List<List<Integer>> lists) { if (k == 0) { lists.add(list);//(*) 发现是这行代码出了问题 System.out.println(lists);//这里打个断点调试 return lists; } for (int i = index; i < n; i++) { list.add(i + 1);//尝试添加 dfs(n, k - 1, i + 1, list,lists); list.remove(list.size() - 1);//回溯,成功与否均进行回溯 } return lists; } }
调试结果为(错误):
[[1, 3], [1, 3]] [[1, 4], [1, 4], [1, 4]] [[2, 3], [2, 3], [2, 3], [2, 3]] [[2, 4], [2, 4], [2, 4], [2, 4], [2, 4]] [[3, 4], [3, 4], [3, 4], [3, 4], [3, 4], [3, 4]]
查了一些资料才思考出原因:list.add方法传入的是地址而不是值。
因此:每一次lists.add(list),是将list的引用传入了,每次回溯进行修改的时候,lists中已经添加的引用值也会改变,才会出现每次打印lists时,都会不同
2. 正确写法:将(*)代码重写,根据list中的值重新new一个对象即可
lists.add(new ArrayList<>(list)); //(*)
断点处调试结果为:
[[1, 2]] [[1, 2], [1, 3]] [[1, 2], [1, 3], [1, 4]] [[1, 2], [1, 3], [1, 4], [2, 3]] [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4]] [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
最终返回正确结果为
[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]