现在的位置: 首页 > 综合 > 正文

LeetCode(91)Subset II

2014年10月16日 ⁄ 综合 ⁄ 共 2296字 ⁄ 字号 评论关闭

题目如下:

Given a collection of integers that might contain duplicates, S, return all possible subsets.
Note:
Elements in a subset must be in non-descending order.The solution set must not contain duplicate subsets.For example,If S = [1,2,2], a solution is:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

分析如下:

和上一题基本一样,区别在于这道题目的输入集合中的元素可能有重复,要求输出的子集合中过滤掉重复。可以先得到一个有重复的结果,再用个set或者hash滤重(使用0(N)空间复杂度)

我的代码:

第一版本,先迭代再滤重版本

// 先迭代再滤重
class Solution {
public:
    vector<vector<int> > subsetsWithDup(vector<int> &S) {
        int length=(int)S.size();
        vector<vector<int>> res(1);
        if(length==0)
            return res;
        std::sort(S.begin(), S.end());
        for(int i=0;i<S.size();++i){
            int j=(int)res.size();
            while(--j>=0){
                res.push_back(res[j]);
                res.back().push_back(S[i]);
            }
        }
        set<vector<int> > filter_set;
        for(int i=0;i<res.size();++i)
            filter_set.insert(res[i]);
        res.clear();
        for(set<vector<int> >::iterator it=filter_set.begin();it!=filter_set.end();it++)
            res.push_back(*it);
        return res;
    }
};

第二版本,先递归再滤重版本

//先递归再滤重
class Solution {
public:
        set<vector<int> > subsets_(vector<int> &S, int i){
        if(i==-1){
            vector<int> set_tmp;
            set<vector<int> > set_set_tmp;
            set_set_tmp.insert(set_tmp);
            return set_set_tmp;
        }
        set<vector<int> >  set_vec_tmp = subsets_(S,i-1);
        set<vector<int> >  set_vec_out = set_vec_tmp;
        set<vector<int> >::iterator set_vec_it=set_vec_tmp.begin();
        for(set_vec_it=set_vec_tmp.begin();set_vec_it!=set_vec_tmp.end();set_vec_it++){
            vector<int> vec_tmp=*set_vec_it;
            vec_tmp.push_back(S[i]);
            std::sort(vec_tmp.begin(),vec_tmp.end());
            set_vec_out.insert(vec_tmp);
        }
        return set_vec_out;
    }
    vector<vector<int> > subsetsWithDup(vector<int> &S) {
        int length=(int)S.size();
        vector<vector<int>> res;
        set<vector<int>> tmp;
        if(length==0)
            return res;
        length--;
        tmp=subsets_(S,length);
        for(set<vector<int> >::iterator it=tmp.begin();it!=tmp.end();it++){
            vector<int> small_vec=*it;
            res.push_back(small_vec);
        }
        return res;
    }
};

第三版本

我还没怎么看懂,不使用set不使用hash直接滤重,官网上看到的答案如下。

//不使用set或者hash直接滤重
class Solution {
public:
    vector<vector<int> > subsetsWithDup(vector<int> &S) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function            
        vector<int> path;
        vector<vector<int> > result;

        sort(S.begin(), S.end());
        sub(S, 0, path, result);
        return result;
    }

    void sub(vector<int> &s, int begin, vector<int> &path, vector<vector<int> > &result) {
        result.push_back(path);

        for (int i = begin; i < s.size(); ++i) {
            if (i != begin && s[i] == s[i - 1]) continue;

            path.push_back(s[i]);
            sub(s, i + 1, path, result);
            path.pop_back();
        }
    }
};

参考资料:

(1) http://discuss.leetcode.com/questions/253/subsets

抱歉!评论已关闭.