回溯算法笔记

算法适用题型

搜索, 在一个集合中寻找符合特定条件子空间
关键字:集合, 组合
类似于棋盘上填格子。
例:
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()

你可能感兴趣的:(leetcode)