Subsets

Given a set of distinct integers, nums, return all possible subsets.

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

求组合的题目,非常经典,排列和组合的题目都需要枚举所有情况,使用search来做.区别在于Permutations有顺序,下一个元素可以是当前元素的前面,组合没有顺序,需要一直朝后走防止重复组合.

1.首先是第一个思路,就是backtracking + recursive的思路.先找第一个元素,之后朝后添加第二个元素,一直到到达数组的末尾.每走一步就把当前结果加入最终结果集中.因为数组没有重复元素,每一个的开始位置又不一样,保证了组合非重复.

代码如下:

    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        if not nums:
            return []
        nums.sort()
        res = []
        self.dfs(nums, 0 , res, [])
        res.append([])
        return res
        
    def dfs(self, nums, start, res, sub):
        for i in xrange(start, len(nums)):
            sub.append(nums[i])
            res.append(sub+[]) #每走一步就把当前结果加入最终结果集中
            self.dfs(nums, i + 1, res, sub) #关键步骤,保证一直朝后添加元素
            sub.pop()  #backtracking
        

第二种方法, 循环解法,主要是每次在当前已有的结果上再加上一维,也是常见的组合方法.举例来自Yanbing Shi博客.

起始subset集为:[]
添加S0后为:[], [S0]
添加S1后为:[], [S0], [S1], [S0, S1]
添加S2后为:[], [S0], [S1], [S0, S1], [S2], [S0, S2], [S1, S2], [S0, S1, S2]
红色subset为每次新增的。显然规律为添加Si后,新增的subset为克隆现有的所有subset,并在它们后面都加上Si。

代码如下:

class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        #add a number to the already result once for a time
        res = []
        res.append([])
        for i in xrange(len(nums)):
            n = len(res)
            for j in xrange(n):
                sub = res[j]
                res.append(sub + [nums[i]])
                
        return res
原文地址:https://www.cnblogs.com/sherylwang/p/5704148.html