leetcode -day31 Subsets I II

1、


Subsets

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

分析:想到的方法是首先进行排序,从头到尾一次选择要不要该元素,可以递归实现,如下代码。

class Solution {
public:
    vector<vector<int> >*  v;
    vector<vector<int> > subsets(vector<int> &S) {
    
        v = new vector<vector<int> >();
        //先排序
        sort(S.begin(),S.end());

        vector<int> res;
        generate(res, S, 0);
        return *v;
    }
    //对每一个元素有放与不放两种选择
    void generate(vector<int> res, vector<int> &S, int i)
    {
        if(i == S.size())
        {
            v->push_back(res);
            return;
        }
        else
        {
            generate(res, S, i+1);//不放当前元素
            res.push_back(S[i]); //放入当前元素
            generate(res, S, i+1);
        }
    }
};

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

分析:此题和上题类似,就是有了重复元素,想法也是先进行排序,排序后,从头到尾遍历,记录每个元素的个数,每个子集中有0-i个指定元素(一共i个),代码如下:

class Solution {
public:
    vector<vector<int> >*  v;
    vector<vector<int> > subsetsWithDup(vector<int> &S) {
    
        v = new vector<vector<int> >();
        //先排序
        sort(S.begin(),S.end());

        vector<int> res;
        generate(res, S, 0,0,0);
        return *v;
    }
    //pre: 排序后前一个元素 num: 前一个元素出现的次数
    void generate(vector<int> res, vector<int> &S, int i,int pre,int num)
    {
        if(i == S.size())
        {   
            v->push_back(res);
            for(int j=1; j<=num; ++j){
                res.push_back(pre); //放入之前元素
                v->push_back(res);
            }
            return;
        }
        else if(pre != S[i] || num < 1 ) //与之前元素不同或者是首次
        {
            if(num < 1){
                generate(res,S,i+1,S[i],1);
            }else{
                generate(res, S, i+1,S[i],1);//放入0个元素
                for(int j=1; j<=num; ++j){
                    res.push_back(pre); 
                    generate(res, S, i+1,S[i],1);//放入i个元素后从当前位置开始
                }
            }
        }else{
            pre = S[i];
            generate(res, S, i+1,pre,num+1);
        }
    }
};


参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

xiao囡囡

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值