LeetCode Subsets II

90. Subsets II

Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: [1,2,2]
Output:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

求一个“集合”的所有子集,和LeetCode Subsets的区别是本题中,原始“集合”可能包含重复元素,和LeetCode Permutations II很类似。
只需在LeetCode Subsets的基础上增加一个判断,如果在递归的时候发现某个元素和上一个元素相同,则不添加,即不再以该元素独立新开一个递归下去。
举个例子,样例中的{1,2,2},第一次递归的时候,我们会尝试分别以1,2和2递归,但是发现第二个2和前一个元素2相同,所以我们不再以第二个2开一个新的递归下去。但是我们在以第一个2开递归的时候,发现后面有一个2时,并不阻止这个2加到原有的集合中去,也就是子集{2,2}还是会产生的。
完整代码如下:

class Solution {
public:
    void work(vector<vector<int> >& ans, vector<int>& cand, vector<int>& nums, int step)
    {
        ans.push_back(cand);
        for (int i = step; i < nums.size(); i++) {
            if (i != step && nums[i] == nums[i – 1]) { // caution:i != step
                continue;
            }
            cand.push_back(nums[i]);
            work(ans, cand, nums, i + 1);
            cand.pop_back();
        }
    }
    vector<vector<int> > subsetsWithDup(vector<int>& nums)
    {
        vector<vector<int> > ans;
        vector<int> cand;
        sort(nums.begin(), nums.end()); // 先对原数组排序
        work(ans, cand, nums, 0);
        return ans;
    }
};

注意判断的条件是i!=step,而不是i!=0,因为如果是i!=0,则{2,2}这种情况也会被禁止掉。
本代码提交AC,用时6MS。

Leave a Reply

Your email address will not be published. Required fields are marked *