I'm trying to solve a recursion/DFS/backtracking problem, which is return all possible subsets for a num; for example: Input: nums = [1,2,3] Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
So I wrote the following code:
class Solution {
public List<List<Integer>> subsets(int[] nums) {
if (nums == null) return new ArrayList<>();
List<List<Integer>> result = new ArrayList<>();
List<Integer> numlist = new ArrayList<>();
dfs(nums, 0, numlist, result);
return result;
}
private void dfs(int[] nums, int index, List<Integer> numlist, List<List<Integer>> set) {
if (index == nums.length) {
// set.add(numlist); // ->>>>>>>>>> WRONG
set.add(new ArrayList<>(numlist)); // ->>>>>>>>> RIGHT
return;
}
// left:
numlist.add(nums[index]);
dfs(nums, index + 1, numlist, set);
// backtrack:
numlist.remove(numlist.size() - 1); // delete the last char in the sb and backtrack
dfs(nums, index + 1, numlist, set);
}
}
I am very confused that, in the line I marked as WRONG and RIGHT, why is that when I use "set.add(numlist)" the result will be all empty which is [[],[],[],[],[],[]], but when I changed it to "set.add(new ArrayList<>(numlist))", the result is correct. Why do I have to create a new value copy of the numlist to be added to the result? I thought JAVA is always pass-by-reference, so everytime it should be the value of numlist to be added to the result, and then remain unchanged, but why the the result arraylist changed if I didn't create a copy of the value?
I am very confused and thought it should be something related to reference/value.