首页 > 代码库 > Subsets II

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


解法2,3 都算是递归的backtrace, 遍历所有组合,每层上都要注意避免重复
解法1,4都是按照每加一个元素都double一下集合的思路,一个是迭代,一个是递归。


class Solution {
public:
    vector<vector<int> > subsetsWithDup(vector<int> &S) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
        vector<vector<int>> ret;
        int cnt = S.size();
        if (cnt == 0) return ret;
        sort(S.begin(), S.end());
        
        // 1
        /*
        ret.push_back(vector<int>());
        for (int i = 0; i < cnt;) {
            int osize = ret.size();
            int j = i + 1;
            while (j < cnt && S[j] == S[i]) ++j;
            int clen = j - i;
            for (int k = 0; k < osize; ++k) {
                for (int t = 1; t <= clen; ++t) {
                    ret.push_back(ret[k]);
                    ret.back().insert(ret.back().end(), t, S[i]);
                }
            }
            
            i = j;
        }
        */
        
        // 2
        /*
        vector<int> cur;
        genSets1(ret, cur, S, 0);
        */
        
        // 3
        /*
        vector<int> cur;
        genSets2(ret, cur, S, 0);
        */
        
        // 4
        genSets3(ret, S, 0);
        
        return ret;
    }
    
private:
    void genSets1(vector<vector<int>> &ret, vector<int> &cur, vector<int> &S, int cpos) {
        if (cpos == S.size()) {
            ret.push_back(cur);
            return;
        }
        
        int j = cpos + 1;
        while (j < S.size() && S[j] == S[cpos]) ++j;
        int clen = j - cpos;
        int osize = cur.size();
        for (int i = 1; i <= clen; ++i) {
            cur.push_back(S[cpos]);
            genSets1(ret, cur, S, j);
        }

        cur.resize(osize);
        genSets1(ret, cur, S, j);
    }
    
    void genSets2(vector<vector<int>> &ret, vector<int> &cur, vector<int> &s, int cpos) {
        ret.push_back(cur);
        if (cpos == s.size()) return;
        
        int preval = 0;
        for (int i = cpos; i < s.size(); ++i) {
            if (i > cpos && preval == s[i]) continue;
            preval = s[i];
            cur.push_back(s[i]);
            genSets2(ret, cur, s, i + 1);
            cur.pop_back();
        }
    }
    
    void genSets3(vector<vector<int>> &ret, vector<int> &S, int cpos) {
        if (cpos == S.size()) {
            ret.push_back(vector<int>());
            return;
        }
        
        int j = cpos;
        while (j < S.size() && S[j] == S[cpos]) ++j;
        int clen = j - cpos;
        genSets3(ret, S, j);
        int osize = ret.size();
        for (int i = 0; i < osize; ++i) {
            for (int j = 1; j <= clen; ++j) {
                ret.push_back(vector<int>(j, S[cpos]));
                ret.back().insert(ret.back().end(), ret[i].begin(), ret[i].end());
            }
        }
    }
};