[leetcode 78 & 90, Medium] Subsets I and II

来源:互联网 发布:淘宝内衣店铺简介 编辑:程序博客网 时间:2024/05/16 15:52

Problem:

I

Given a set of distinct integers, 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,3], a solution is:

[  [3],  [1],  [2],  [1,2,3],  [1,3],  [2,3],  [1,2],  []]

II

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],  []]

Analysis:

Solutions:

(I) Recursive method:

void getCombine(vector<vector<int> > &setCombine, vector<int> &combine, vector<int> &S, int startIndex, int num){        if(num==1){            for(int i=startIndex; i<S.size(); ++i){                combine.push_back(S[i]);                setCombine.push_back(combine);                combine.pop_back();            }        }else{            for(int i=startIndex; i<S.size(); ++i){                combine.push_back(S[i]);                getCombine(setCombine, combine, S, i+1, num-1);                combine.pop_back();            }        }    }        vector<vector<int> > subsets(vector<int> &S) {                std::sort(S.begin(), S.end());                vector<vector<int> > colSubset;        vector<int> subset;        colSubset.push_back(subset); //Empty subset.                for(int k=1; k<=S.size(); ++k)            getCombine(colSubset, subset, S, 0, k);        return colSubset;    }

Non-Recursive method:

    vector<int> Union(const vector<int>& left, const vector<int>& right)    {        vector<int> r_set;        for(int i = 0; i < left.size(); ++i)            r_set.push_back(left[i]);                    for(int i = 0; i < right.size(); ++i)            r_set.push_back(right[i]);                    return r_set;    }        vector<vector<int> > subsets(vector<int> &S) {        vector<vector<int> > r_subsets;        vector<int> empty;        r_subsets.push_back(empty);        if(S.empty())            return r_subsets;        sort(S.begin(), S.end());        int max_size = S.size();        vector<vector<vector<int> > > subsets_by_size;        subsets_by_size.resize(max_size);        for(int size = 0; size < max_size; ++size) {            if(size == 0) {                for(int i = 0; i < S.size(); ++i) {                    vector<int> subset;                    subset.push_back(S[i]);                    subsets_by_size[size].push_back(subset);                }            } else {                for(int i = 0; i < subsets_by_size[0].size(); ++i) {                    for(int j = 0; j < subsets_by_size[size - 1].size(); ++j) {                        if(subsets_by_size[0][i][0] < subsets_by_size[size - 1][j][0])                            subsets_by_size[size].push_back(Union(subsets_by_size[0][i], subsets_by_size[size - 1][j]));                    }                }            }        }                for(int i = 0; i < max_size; ++i) {            for(int j = 0; j < subsets_by_size[i].size(); ++j)                r_subsets.push_back(subsets_by_size[i][j]);        }                return r_subsets;    }
(II)

    vector<int> Union(const vector<int>& left, const vector<int>& right)    {        vector<int> r_set;        for(int i = 0; i < left.size(); ++i)            r_set.push_back(left[i]);                    for(int i = 0; i < right.size(); ++i)            r_set.push_back(right[i]);                    return r_set;    }        vector<vector<int> > subsetsWithDup(vector<int> &S) {        vector<vector<int> > r_subsets;        vector<int> empty;        r_subsets.push_back(empty);        if(S.empty())            return r_subsets;        sort(S.begin(), S.end());        int max_size = S.size();        vector<vector<vector<int> > > subsets_by_size;        subsets_by_size.resize(max_size);        for(int size = 0; size < max_size; ++size) {            if(size == 0) {                for(int i = 0; i < max_size;) {                    vector<int> subset;                    if(i == max_size - 1 || S[i] < S[i + 1]) {                        subset.push_back(S[i]);                        subsets_by_size[size].push_back(subset);                        ++i;                    } else {                        int sum_same = 0;                        for(int j = i; j < max_size; ++j) {                            if(S[i] == S[j]) ++sum_same;                            else break;                        }                                                    for(int j = 0; j < sum_same; ++j) {                            subset.push_back(S[i]);                            subsets_by_size[size].push_back(subset);                        }                        i += sum_same;                    }                }            } else {                for(int i = 0; i < subsets_by_size[0].size(); ++i) {                    for(int j = 0; j < subsets_by_size[size - 1].size(); ++j) {                        if(subsets_by_size[0][i][0] < subsets_by_size[size - 1][j][0])                            subsets_by_size[size].push_back(Union(subsets_by_size[0][i], subsets_by_size[size - 1][j]));                    }                }            }        }                for(int i = 0; i < max_size; ++i) {            for(int j = 0; j < subsets_by_size[i].size(); ++j)                r_subsets.push_back(subsets_by_size[i][j]);        }                return r_subsets;    }
Java:


Python: