zoukankan      html  css  js  c++  java
  • 17 子集

    原题网址: https://www.lintcode.com/zh-cn/problem/subsets/

    给定一个含不同整数的集合,返回其所有的子集

     注意事项

    子集中的元素排列必须是非降序的,解集必须不包含重复的子集

    样例

    如果 S = [1,2,3],有如下的解:

    [
      [3],
      [1],
      [2],
      [1,2,3],
      [1,3],
      [2,3],
      [1,2],
      []
    ]
    
    挑战 

    你可以同时用递归与非递归的方式解决么?

    标签 
     
    方法1.非递归
    要求子集中元素排列升序,可以将原数组升序排列,然后依次加入到结果数组中。
    举个例子,输入数组【1,2,3】,首先将【1】push到result中;
    然后从原数组中取出元素2,创建临时数组temp1=【1】,将2 push到temp1中得到【1,2】,将temp1 push到result中,再将【2】本身push到result中,此时result中有【1】,【1,2】,【2】;
    从原数组中取出元素3,创建临时数组依次等于【1】,【1,2】,【2】,将3 分别push进去得到【1,3】,【1,2,3】,【2,3】,再将临时数组push到result中,再将【3】本身push到result中,over;
    最后一定记得再push一个空数组到result中。
     
    AC代码:
    class Solution {
    public:
        /**
         * @param nums: A set of numbers
         * @return: A list of lists
         */
        vector<vector<int>> subsets(vector<int> &nums) {
            // write your code here
             vector<vector<int>> result;
          if (nums.empty())
          {
              result.push_back(nums);
              return result;
          }
          sort(nums.begin(),nums.end());
          vector<int> first;
          first.push_back(nums[0]);
          result.push_back(first);
    
          for (int i=1;i<(int)nums.size();i++)
          {
              int size1=result.size();
              for (int j=0;j<size1;j++)
              {
                  vector<int> temp1= result[j];
                  temp1.push_back(nums[i]);
                  result.push_back(temp1);
              }
              vector<int> temp2;
              temp2.push_back(nums[i]);
              result.push_back(temp2);
          }
          vector<int> nul;
          result.push_back(nul);
          return result;
        }
    };

    方法2.递归   参考 https://www.cnblogs.com/felixfang/p/3775712.html  与 https://www.cnblogs.com/eudiwffe/p/6558744.html

     思路:所谓子集,就是包含原集合中的一些元素,不包含另一些元素。如果单独看某一个元素,它都有两种选择:"被包含在当前子集中"和"不被包含在当前子集中",对于元素个数为n、且不含重复元素的S,子集总数是2n。因此我们可以遍历S的所有元素,然后用递归考虑每一个元素包含和不包含的两种情况。

    深度优先搜索。

        

    图源:https://blog.csdn.net/aphysia/article/details/77849042

    AC代码:

    class Solution {
    public:
        /**
         * @param nums: A set of numbers
         * @return: A list of lists
         */
        vector<vector<int>> subsets(vector<int> &nums) {
            // write your code here
            vector<vector<int>> result;
        if (nums.empty())
        {
            result.push_back(nums);
            return result;
        }
        sort(nums.begin(),nums.end());
        vector<int> v;
        subsetCore(nums,v,0,result);
        return result;
        }
        
        void subsetCore(vector<int> &nums,vector<int> &v,int pos,vector<vector<int>> &result )
    {
        if (pos==nums.size())//遍历所有元素,即只要POS还指向某个元素,就要进行是否在当前子集的判断;
        {
            result.push_back(v);
            return ;
        }
        vector<int> v2(v); //v和v2是当前正在生成的子集;
        v.push_back(nums[pos]);//v包含当前元素;
        subsetCore(nums,v,pos+1,result);
        subsetCore(nums,v2,pos+1,result); //v2不包含当前元素;
    }
    
    };
     
     
  • 相关阅读:
    组合数计算--动态规划
    ListView 的position和id的区别
    android View 关于transient
    BlockingQueue深入分析
    栈的实现(JAVA)
    队列的实现(JAVA)
    《算法导论》读书笔记之第11章 散列表
    java 二叉搜索树
    桶排序
    排序算法的稳定性
  • 原文地址:https://www.cnblogs.com/Tang-tangt/p/8947572.html
Copyright © 2011-2022 走看看