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