回溯法
回溯法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 result
def 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()