回溯法
回溯法Backtracking(找所有的可能)递归:
- 类似枚举,一层一层向下递归,尝试搜索答案。
- 找到答案: => 返回答案,并尝试别的可能
- 未找到答案: => 返回上一层递归,尝试别的可能
实战
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
注意:在设计算法时,要谨记我们之前所说的递归四要素:
- 接收的参数
- 返回值
- 终止条件
- 递归拆解:如何递归下一层
class Solution:def subsets(self, nums: List[int]) -> List[List[int]]:# 扩展法# [ ]# [1]# [2] [1,2]# [3] [1,3] [2,3] [1,2,3]# res = []# res.append([])# for num in nums:# temp = [] # 用于存储扩展后的若干子集# for i in res:# r = list(i) # 相当于copy,避免引用传递# r.append(num)# temp.append(r)# for r in temp:# res.append(r)# return res# 方法二:回溯法:[1,2,3] 子集长度介于0--3# Time Complexity:O(N*2^N)# Space Complexity:O(N*2^N)# 长度# 0 [ ]# 1 [1] [2] [3]# 2 [1,2] [1,3] [2,3]# 3 [1,2,3]result = [[]]# 因为等于0 的长度(空集)已经加进去了for i in range(1,len(nums)+1): self.backtracking(nums,result,i,0,[])return resultdef backtracking(self,nums,result,lenght,index,subset):# 终止条件:子集的长度 == 要找的长度if len(subset) == lenght:temp = list(subset) # 相当于copy,避免引用传递 list(subset) 等价于 subset[:]result.append(temp)return# 循环部分for i in range(index,len(nums)):subset.append(nums[i])self.backtracking(nums,result,lenght,i+1,subset)subset.pop() # 当backtracking出来一定要把新加入的元素删除掉# 方法三 DFS # Time Complexity:O(N*2^N)# Space Complexity:O(N*2^N)# result = []# self.dfs(nums,result,0,[])# return result# def dfs(self,nums,result,index,subset):# result.append(subset[:])# # 终止条件# if index == len(nums):# return # for i in range(index,len(nums)):# subset.append(nums[i])# self.dfs(nums,result,i+1,subset)# subset.pop()