码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode: Subsets I & II

时间:2015-05-05 15:47:23      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:

1 Subset

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

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

思路:对于这样的题目,已经有一个直观的思路,就是DFS,使用递归。
这里面有两种递归思路,一种就是将问题拆分成子问题,如先求[1,2]的子集,根据[1,2]的子集求[1,2,3]的子集

思路一

可以用递推的思想,观察S=[], S =[1], S = [1, 2] 时解的变化。

技术分享

可以发现S=[1, 2] 的解就是 把S = [1]的所有解末尾添上2,然后再并上S = [1]里面的原有解。因此可以定义vector<vector<int> > 作为返回结果res, 开始时res里什么都没有,第一步放入一个空的vecotr<int>,然后这样迭代n次,每次更新res 内容,最后返回res。

class Solution{
public:
    vector<vector<int> > subsets(vector<int> & S){
        vector<vector<int> > results;
        vector<int> empty;
        if (S.empty()){
            
            results.push_back(empty);
            return results;
        }
        sort(S.begin(),S.end());
        vector<int> result;
        result.push_back(S[0]);
        results.push_back(result);
        for (int i = 1 ; i < S.size(); i++){
            vector<int> result;
            result.push_back(S[i]);
            
            int size = results.size();
            for (int j = 0 ; j < size; j++){
                vector<int> r(results[j].begin(),results[j].end());
                r.push_back(S[i]);
                results.push_back(r);
            }
            results.push_back(result);
        }
        results.push_back(empty);
        return results;
    }
};

另一种递归思路就是使用DFS

class Solution{
public:
    vector<vector<int> > subsets(vector<int> & S){
        vector<vector<int> > results;
        vector<int> result;
        results.push_back(result);
        sort(S.begin(),S.end());
        dfs(0,result,S,results);
        return results;
    }
    void dfs(int index, vector<int> & result, vector<int> & S, vector<vector<int> > & results){
        for (int i = index; i < S.size(); i++){
            result.push_back(S[i]);
            results.push_back(result);
            dfs(i+1,result,S,results);
            result.pop_back();
        }
    }
};

2 Subsets II

Given a collection of integers that might contain duplicates, nums, 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 nums = [1,2,2], a solution is:

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

我们以S=[1,2,2]为例:

技术分享

可以发现从S=[1,2]变化到S=[1,2,2]时,多出来的有两个子集[2,2]和[1,2,2],这两个子集,其实就是 [2], [1,2]末尾都加上2 而产生。而[2], [1,2] 这两个子集实际上是 S=[1,2]的解到 S=[1]的解 新添加的部分。

因此,若S中有重复元素,可以先排序;遍历过程中如果发现当前元素S[i] 和 S[i-1] 相同,那么不同于原有思路中“将当前res中所有自己拷贝一份再在末尾添加S[i]”的做法,我们只将res中上一次添加进来的子集拷贝一份,末尾添加S[i]。

 

class Solution{
public:
    vector<vector<int> > subsetsWithDup(vector<int> &S){
        vector<vector<int> > results;
        vector<int> empty;
        results.push_back(empty);
        if (S.empty())
            return results;
        sort(S.begin(),S.end());
        int m = 0;
        int start = 0;
        for (int i = 0 ; i < S.size(); i++){
            if (i > 0 && S[i] == S[i-1]){
                start = m;    
            }
            else{
                start = 0;
            }
            int size = results.size();
            for (int j = start; j < size; j++){
                vector<int> r(results[j].begin(),results[j].end());
                r.push_back(S[i]);
                results.push_back(r);
            }
            m = size;
        }
        return results;
    }
};

 

同样有另一种解法:

class Solution {
public:
  
    
    vector<vector<int> > subsetsWithDup(vector<int> & S){
        vector<vector<int> > results;
        vector<int> result;
        results.push_back(result);
        sort(S.begin(),S.end());
        dfs(0,result,S,results);
        return results;
    }
    void dfs(int index, vector<int> & result, vector<int> & S, vector<vector<int> > & results){
        for (int i = index; i < S.size(); i++){
            if (i > index && S[i] == S[i-1])
                continue;
            result.push_back(S[i]);
            results.push_back(result);
            dfs(i+1,result,S,results);
            result.pop_back();
        }
    }
};

 

 

LeetCode: Subsets I & II

标签:

原文地址:http://www.cnblogs.com/yxzfscg/p/4479147.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!