为了方便放在leetcode讨论区所以翻译成了英文 : )
LeetCode 90 Subsets II C++ 12ms 100% Sloution
We know that a large number of repeated calculations are generated in the statistical subset, so our goal is to use the idea of dynamic programming, consider how to maximize the use of remembered subsets, and reduce the number of repeated operations.
Let’s look at an example:
[1,2,2,2,3,3,4,]
The usual practice is to first sort the vector, then start with 1 as the starting number, then calculate with 2 as the starting number… skip the repeated starting number during the calculation.
[1],[1,2],[1,2,2]…[2],[2,2],[2,2,2],[2,2,2,3]…
However, it is obvious that such a calculation method has already calculated all the subsets with 2 as the starting number when calculating the subset with the starting number of 1.
Make full use of the calculated subset:
So we can make full use of the calculated subset. If we still calculate backwards, we can decompose the operation into computational units that correspond to the numbers in the original set.
original set : {1,2,2,2,3,3,4}
1 : {[1]}
2 : {[2], [2,1]}
2 : {[2,2], [2,2,1],
2 : {[2,2,2], [2,2,2,1]}
3 : {[3,1], [3,2], [3,2,1], [3,2,2], [3,2,2,1], [3,2,2,2,], [3,2,2,2,1]}
…
We can easily find such a rule:
-
If the number representing the current cell is the same as the previous one:
You only need to combine the numbers representing the current calculation unit with all the subsets in the previous calculation unit to get a new, non-repeating subset. -
If the number representing the current cell is different from the previous one:
You only need to combine the numbers representing the current calculation unit with all the subsets in all the previous calculation units to get a new, non-repeating subset.
Continuously taking new numbers from the original collection and repeating this process, we can do all the calculations without wasting any calculated subsets.
Here is the code:
class Solution {
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<vector<int>> result;
if(nums.size() > 0){
vector<vector<vector<int>>> A;
sort(nums.begin(), nums.end());
result.push_back({});
for(int i = 0; i < nums.size(); i ++) {
vector<vector<int>> B;
if(0 == i || (i - 1 >=0 && nums[i] != nums[i-1])) {
B.push_back({nums[i]});
result.push_back({nums[i]});
for(int j = 0; j < i; j++) {
for(int k = 0; k < A[j].size(); k++){
vector<int> C(A[j][k]);
C.push_back({nums[i]});
B.push_back(C);
result.push_back(C);
}
}
}else{
for(int k = 0; k < A[i - 1].size(); k++){
vector<int> C(A[i - 1][k]);
C.push_back({nums[i]});
B.push_back(C);
result.push_back(C);
}
}
A.push_back(B);
}
}
return result;
}
};