• LeetCode: Subsets I & II


    1 Subset

    https://leetcode.com/problems/subsets/

    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。

    
    

    特别注意:蓝色代码一定要有,因为在接下来的循环中不断在填充results,所以在循环前要得到size

    
    
    class Solution{
    public:
        vector<vector<int> > subsets(vector<int> & S){
            vector<vector<int> > results;
            vector<int> result;
            if (S.empty()){
                results.push_back(result);
                return results;
            }
            results.push_back(result);
            sort(S.begin(),S.end());
            result.push_back(S[0]);
            results.push_back(result);
            for (int i = 1 ; i < S.size(); 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);
                }
            }
            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

    https://leetcode.com/problems/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();
            }
        }
    };
  • 相关阅读:
    Linux磁盘与文件系统操作命令
    Linux 进程管理命令
    文件备份与压缩命令
    Linux系统命令
    CentOS6和CentOS7的区别
    nginx安装配置
    docker的容器和镜像的清理
    Zabbix-Agent配置文件详解
    k8s 获取登录token命令
    vmware 端口转发设置
  • 原文地址:https://www.cnblogs.com/yxzfscg/p/4479147.html
Copyright © 2020-2023  润新知