diff --git a/solutions/90. Subsets II.md b/solutions/90. Subsets II.md index a3056de..02ff3b7 100644 --- a/solutions/90. Subsets II.md +++ b/solutions/90. Subsets II.md @@ -17,7 +17,8 @@ / \ / \ / \ / \ [1 2 2] [1 2] X [1] [2 2] [2] X [] ``` -需要注意去掉重复值,即对树进行剪枝: 当前一层的元素(`nums[level-1]`)未被访问且`nums[level]==nums[level-1]`时,当前元素`nums[level]`也不应该访问,即只沿右子树下降。 +需要注意避免重复结果: 如果下一层对应元素满足`nums[level+1] == nums[level]`,若不打算访问当前层对应元素(`nums[level]`),那么也不应该访问下一层对应元素,所以在向右子树下降之前应该跳过重复值,详见代码。 + ## 思路二 此题也可以使用迭代的方式来完成此题。 参考[78. Subsets题解](https://github.com/ShusenTang/LeetCode/blob/master/solutions/78.%20Subsets.md),当处理到第一个2时,此时的子集合为[], [1], [2], [1, 2], @@ -32,33 +33,28 @@ ``` C++ class Solution { private: - void DFS(vector>&res, vector&subset, vector&visited, const vector& nums, int level){ - if(level == nums.size()) { // 叶节点 - res.push_back(subset); + void DFS(const vector&nums, vector>&res, vector&out, int level){ + if(level == nums.size()){ + res.push_back(out); return; } - if(level > 0 && nums[level] == nums[level - 1] && !visited[level - 1]){ - DFS(res, subset, visited, nums, level + 1); // 沿右子树下降 - return; - } + // 左子树 + out.push_back(nums[level]); + DFS(nums, res, out, level+1); + out.pop_back(); - // 沿左子树下降 - visited[level] = true; - subset.push_back(nums[level]); - DFS(res, subset, visited, nums, level + 1); - visited[level] = false; - subset.pop_back(); - // 沿右子树下降 - DFS(res, subset, visited, nums, level + 1); + // 右子树 + int i = level + 1; + while(i < nums.size() && nums[i] == nums[level]) i++; // 避免重复, 唯一和78. Subsets不同的地方 + DFS(nums, res, out, i); } public: vector> subsetsWithDup(vector& nums) { vector>res; - vectorsubset; - vectorvisited(nums.size(), false); + vectorout; sort(nums.begin(), nums.end()); - DFS(res, subset, visited, nums, 0); + DFS(nums, res, out, 0); return res; } };