搜索, 在一个集合中寻找符合特定条件的子空间。
关键字:集合, 组合
类似于棋盘上填格子。
例:
Subset
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
if len(nums) == 0:
return []
ls = [] #每个解的存储地址
res = [] #所有解的存储
self.subsets_helper(nums, ls, res, 0)
return res
def subsets_helper(self, nums, ls, res, pos):
res.append(ls[:])
for i in range(pos, len(nums)):
'''
筛选条件添加位置,如果满足条件就countinue
'''
ls.append(nums[i])
self.subsets_helper(nums, ls, res, i+1)
ls.pop() #返回上一个路口的初始位置
#找子集模板总结
def 主函数(self, 总集合):
if 总集合为[]:
retuen []
ls = 符合条件的子集(初始为[])
res = 用于存储ls(初始为[])
调用helper(总集合, ls, res, 0)进行回溯
return res
def 辅助函数helper(总集合, ls, res, pos)
'''
总集合:
ls:
res:
pos: 指明搜索进行到哪里
'''
if 判断ls是否是解:
res.append(ls[:])
#如果ls是可变数据类型一定要对其进行copy
for i in range(pos, len(总集合)):
if 剪枝条件:
continue
ls.append(总集合[i]) #记录搜索结果
helper(总集合, res, ls, i+1) #继续向下搜索
ls.pop()回溯
回溯大致的模板是这样的,只是思路,具体问题需要具体分析。比如:
字母大小写全排列
class Solution:
def letterCasePermutation(self, S: str) -> List[str]:
if len(S) == 0:
return ''
char = ''
res = []
self.letter_helper(S, char, res, 0)
return res
def letter_helper(self, S, char, res, idx):
if len(char) == len(S):
res.append(char)
for i in range(idx, len(S)):
char = char + S[idx]
self.letter_helper(S, char, res, i+1)
char = char[:len(char)-1]
if S[i].isalpha():
char = char + S[idx].swapcase()
self.letter_helper(S, char, res, i+1)
char = char[:len(char)-1]
Subset2
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
ls = []
res = []
nums.sort()
self.subset_helper(ls, res, nums, 0)
return res
def subset_helper(self, ls, res, nums, pos):
res.append(ls[:])
for i in range(pos, len(nums)):
if i != pos and nums[i] == nums[i-1]:
continue
ls.append(nums[i])
self.subset_helper(ls, res, nums, i+1)
ls.pop()
全排列
全排列略有不同,不是不停下探搜索而是不断缩小总集合范围
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
ls = []
res = []
self.permute_helper(nums, ls, res)
return ress
def permute_helper(self, nums, ls, res):
if len(nums) == 0:
res.append(ls[:])
for i in range(len(nums)):
ls.append(nums[i])
self.permute_helper(nums[:i]+nums[i+1:], ls, res)
#nums[3]可能会报超出范围错误;但是nums[3:]会返回[]
ls.pop()
全排列2
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
ls = []
res = []
nums.sort()
self.permute_helper(nums, ls, res)
return res
def permute_helper(self, nums, ls, res):
if len(nums) == 0:
res.append(ls[:])
for i in range(len(nums)):
if i > 0 and nums[i] == nums[i-1]:
continue
ls.append(nums[i])
self.permute_helper(nums[:i]+nums[i+1:], ls, res)
#nums[3]可能会报超出范围错误;但是nums[3:]会返回[]
ls.pop()
组合
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
ls = []
res = []
self.combine_helper(ls, res, k, 1, n)
return res
def combine_helper(self, ls, res, k, pos, n):
if len(ls) == k:
res.append(ls[:])
for i in range(pos, n+1):
ls.append(i)
self.combine_helper(ls, res, k, i+1, n)
ls.pop()