Subsets II - LeetCode

题目链接

Subsets II - LeetCode

注意点

  • 有重复的数字
  • 数组可能是无序的,要先排序

解法

解法一:递归,只需要在Subsets中递归写法的基础上多加一句if(find(ret.begin(),ret.end(),tmp) == ret.end()) ret.push_back(tmp);j即可,因为已经排序了,所以加进去的如果已经存在就说明是重复的。

class Solution {
public:
    typedef vector<int> v;
    void recursion(int start,v nums,v tmp, vector<v>& ret)
    {
        if(find(ret.begin(),ret.end(),tmp) == ret.end()) ret.push_back(tmp);
        int n = nums.size();
        for(int i = start;i < n;i++)
        {
            tmp.push_back(nums[i]);
            recursion(i+1,nums,tmp,ret);
            tmp.pop_back();
        }
    }
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> ret;
        v tmp;
        recursion(0,nums,tmp,ret);
        return ret;
    }
};


解法二:递归。只需要在Subsets中递归写法的基础上多加一句while(i+1 < n && nums[i] == nums[i+1]) i++;即可,这句话的作用就是把下图中树结点为X的剪枝。

                        []        
                   /          \        
                  /            \     
                 /              \
              [1]                []
           /       \           /    \
          /         \         /      \        
       [1 2]       [1]       [2]     []
      /     \     /   \     /   \    / \
  [1 2 2] [1 2]  X   [1]  [2 2] [2] X  []
class Solution {
public:
    typedef vector<int> v;
    void recursion(int start,v nums,v tmp, vector<v>& ret)
    {
        ret.push_back(tmp);
        int n = nums.size();
        for(int i = start;i < n;i++)
        {
            tmp.push_back(nums[i]);
            recursion(i+1,nums,tmp,ret);
            tmp.pop_back();
            while(i+1 < n && nums[i] == nums[i+1]) i++;
        }
    }
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> ret;
        v tmp;
        recursion(0,nums,tmp,ret);
        return ret;
    }
};

解法三:非递归。在Subsets中非递归写法的基础上进行修改,如果当前数字和上一次循环的数字一样,那么就只能在上一次循环产生的集合后面追加当前数字,而不能在所有集合后面追加

class Solution {
public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        if(nums.empty()) return {};
        sort(nums.begin(),nums.end());
        vector<vector<int>> ret(1);
        int i,j,n = nums.size(),last = nums[0],lastSize = 1;
        for(i = 0;i < n;i++)
        {
            if(last != nums[i])
            {
                last = nums[i];
                lastSize = ret.size();
            }
            int m = ret.size();
            for(j  = m-lastSize;j < m;j++)
            {
                ret.push_back(ret[j]);
                ret.back().push_back(nums[i]);
            }
        }
        return ret;
    }
};

小结

posted @ 2019-03-13 15:40  闽A2436  阅读(133)  评论(0编辑  收藏  举报