zoukankan      html  css  js  c++  java
  • 【Lintcode】018.Subsets II

    题目:

    Given a list of numbers that may has duplicate numbers, return all possible subsets

    Notice

    • Each element in a subset must be in non-descending order.
    • The ordering between two subsets is free.
    • The solution set must not contain duplicate subsets.

    Example

    If S = [1,2,2], a solution is:

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

    题解:

    Solution 1 ()

    class Solution {
    public:
        vector<vector<int> > subsetsWithDup(vector<int> S) {
            vector<vector<int> > res;
            vector<int> v;
            sort(S.begin(), S.end());
            Dfs(S, res, v, 0);
            
            return res;
        }
        
        void Dfs(vector<int> S, vector<vector<int> > &res, vector<int> &v, int pos) {
            res.push_back(v);
            
            for (int i = pos; i < S.size(); ++i) {
                if (i == pos || S[i] != S[i - 1]) {
                    v.push_back(S[i]);
                    Dfs(S, res, v, i + 1);
                    v.pop_back();
                }
            }
        }
    };

      To solve this problem, it is helpful to first think how many subsets are there. If there is no duplicate element, the answer is simply 2^n, where n is the number of elements. This is because you have two choices for each element, either putting it into the subset or not. So all subsets for this no-duplicate set can be easily constructed:

    num of subset

    • (1 to 2^0) empty set is the first subset
    • (2^0+1 to 2^1) add the first element into subset from (1)
    • (2^1+1 to 2^2) add the second element into subset (1 to 2^1)
    • (2^2+1 to 2^3) add the third element into subset (1 to 2^2)
    • ....
    • (2^(n-1)+1 to 2^n) add the nth element into subset(1 to 2^(n-1))

    Then how many subsets are there if there are duplicate elements? We can treat duplicate element as a spacial element. For example, if we have duplicate elements (5, 5), instead of treating them as two elements that are duplicate, we can treat it as one special element 5, but this element has more than two choices: you can either NOT put it into the subset, or put ONE 5 into the subset, or put TWO 5s into the subset. Therefore, we are given an array (a1, a2, a3, ..., an) with each of them appearing (k1, k2, k3, ..., kn) times, the number of subset is (k1+1)(k2+1)...(kn+1). We can easily see how to write down all the subsets similar to the approach above.

    Solution 2 ()

    class Solution {
    public:
        vector<vector<int> > subsetsWithDup(vector<int> &S) {
            vector<vector<int> > res{{}};
            sort(S.begin(), S.end());
            for (int i = 0; i < S.size(); ) {
                int cnt = 0;
                while (cnt + i < S.size() && S[cnt + i] == S[i]) {
                    ++cnt;
                }
                int size = res.size();
                for (int j = 0; j < size; ++j) {
                    vector<int> instance = res[j];
                    for (int k = 0; k < cnt; ++k) {
                        instance.push_back(S[i]);
                        res.push_back(instance);
                    }
                }
                i += cnt;
            }
            return res;
        }
    };

    Solution 3 ()

    class Solution {
    public:
        vector<vector<int> > subsetsWithDup(vector<int> &S) {
            vector<vector<int> > res{{}};
            sort(S.begin(), S.end());
            int size = 1;
            int last = !S.empty() ? S[0] : 0;
               for (int i = 0; i < S.size(); ++i) {
                   if (last != S[i]) {
                       last = S[i];
                       size = res.size();
                   }
                   int newsize = res.size();
                   for (int j = newsize - size; j < newsize; ++j) {
                       res.push_back(res[j]);
                       res.back().push_back(S[i]);
                   }
               }
            return res;
        }
    };
  • 相关阅读:
    去掉DevExpress gridControl控件表头上的的默认英文字母
    【555】folium 更换底图
    github图片不显示问题解决
    厉害了,自己动手实现 LRU 缓存机制!
    一文搞懂 Netty 的整体流程,还有谁不会?
    PageHelper 分页一直有性能问题?
    left join 后用 on 还是 where,区别大了!
    不推荐别的了,IDEA 自带的数据库工具就很牛逼!
    王炸!!IDEA 2021.1 推出语音、视频功能,边写代码边聊天,我真的服了…
    别再面向 for 循环编程了,Spring 自带的观察者模式就很香!
  • 原文地址:https://www.cnblogs.com/Atanisi/p/6866474.html
Copyright © 2011-2022 走看看