var subsets = function(nums=[1,2,3]) {
nums.sort( (a, b) => a - b);
return dfs(nums, 0, [], []);
};
var dfs = function(nums, pos, tmp, res) {
if(nums.length === pos) {
res.push(tmp.slice());
return;
}
// 選
tmp.push(nums[pos]);
dfs(nums, pos+1, tmp, res);
// 不選
tmp.pop()
dfs(nums, pos+1, tmp, res);
return res;
}
console.log(subsets());
I want to find all subsets of nums.
If nums=[1, 2, 3], I hope output is [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
In my code,tmp
is a subset of nums
, and res
is used to save all possible subsets
of nums.
In the 9 line, if I write res.push(tmp)
, then I will print empty array.
But if I write res.push(tmp.slice())
, I can print array with values.
if(nums.length === pos) {
console.log(tmp);
console.log(tmp.slice());
res.push(tmp.slice());
return;
}
If I print both tmp
and tmp.slice()
like above, they both have same value.
I am so confused, how to explain this situation?
Maybe in recusive, res array doesn’t reuse value ?
2
Answers
From the docs, Array.prototype.slice() returns a shallow copy of the array being sliced. If you want to push a shallow copy to the result array, you could replace the line containing the slice method with:
res.push([...tmp]);
When you pass
tmp
todfs
in the recursive call (e.g.dfs(nums, pos+1, tmp, res)
), no copy of it is made; you’re essentially passing a reference to that array and thustmp
always refers to the same one array throughout the execution of the program. Consequently,res.push(tmp)
always adds the same one array tores
, so at the end you end up with multiple references to the same array inres
.After
dfs
is complete,tmp
is cleared because all elements are popped.res
consists of multiple references totmp
which all reflect changes to that array, so you see an array containing multiple empty arrays.Array#slice
makes a shallow copy of the array, sores.push(tmp.slice())
will add a different array each time, avoiding the issue.