Here is a solution to a problem to generate unique subsets of an array nums
:
#include <bits/stdc++.h>
using namespace std;
void solveRec(vector<int> ss, set<vector<int>> &ans, vector<int> &nums, int i)
{
if (i == nums.size())
{
sort(ss.begin(), ss.end());
ans.insert(ss);
return;
}
ss.push_back(nums[i]);
solveRec(ss, ans, nums, i + 1);
ss.pop_back();
solveRec(ss, ans, nums, i + 1);
}
This function takes an integer array nums
as input along with a set of vectors ans
to store unique subsets. While passing the vector ss
for storing current subset by value produces the correct answer, passing it by reference does not, why could this be?
let nums
be 4 4 4 1
passing by reference (incorrect) produces:
1
1 1
1 1 4
1 4
1 4 4
1 4 4 4
passing by value (correct) produces:
1
1 4
1 4 4
1 4 4 4
4
4 4
4 4 4
Please help!!!
When ss
is passed by reference, all mutations that happen to ss
are to a single vector instance, which is shared by all execution contexts of the function solveRec
. As a consequence, sort(ss.begin(), ss.end());
has no "local" effect. The negative effects of this kick in when ss.pop_back();
is executed. The intention of this instruction is to remove the same value that was added to ss
with the ss.push_back(nums[i])
call that appears two lines earlier. But this is no longer guaranteed, because in the mean time that ss
has been sorted, and so the popped element might be a different value.
With the call-by-value version of the code, the sort
call has an effect only on the local copy of ss
, and not to the ss
of the caller.
If you leave out the sort
call, it will work also with the pass-by-reference version, but then obviously the generated subsets will not be sorted. You could do that afterwards.