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不包含当前元素;
}

};

 

 
 
posted @ 2018-04-25 21:59  eeeeeeee鹅  阅读(225)  评论(0编辑  收藏  举报