回溯算法
回溯算法可以解决以下几类问题:
- 组合问题:N个数里面按一定规则找出k个数的集合
- 切割问题:一个字符串按一定规则有几种切割方式
- 子集问题:一个N个数的集合里有多少符合条件的子集
- 排列问题:N个数按一定规则全排列,有几种排列方式
- 棋盘问题:N皇后,解数独
77.组合
class Solution:
def __init__(self):
self.res=[] #记录所有路径
self.track=[]
def combine(self, n: int, k: int) -> List[List[int]]:
self.backtrack(1,n,k)
return self.res
def backtrack(self,start,n,k):
if k==len(self.track):
self.res.append(self.track.copy())
return
for i in range(start,n+1):
self.track.append(i)
self.backtrack(i+1,n,k)
self.track.pop()
216.组合总和Ⅲ
关键操作和逻辑:在进行循环前先判断是否需要进行剪枝操作。
class Solution:
def __init__(self):
self.path=[]
self.res=[]
def combinationSum3(self, k: int, n: int) -> List[List[int]]:
self.backtrack(0,n,k,1)
return self.res
def backtrack(self,current_sum,target,k,start):
if k==len(self.path):
if current_sum==target:
self.res.append(self.path.copy())
return
for i in range(start, 10):
if current_sum + i > target: # 提前剪枝
continue
self.path.append(i)
self.backtrack(current_sum + i, target, k, i + 1)
self.path.pop()
17.电话号码的字母组合
个人觉得最关键的地方是怎么处理映射的问题,其他都还好,就是正常的回溯解决方法
class Solution:
#映射的解决方案:用个字典不就行了?!以后要记住这种质朴的方法
mapping=["","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]
def __init__(self):
self.res=[]
self.track=[]
def letterCombinations(self, digits: str) -> List[str]:
self.backtrack(digits,0)
return self.res
def backtrack(self,digits,start):
if not digits:
return
if len(self.track)==len(digits):
self.res.append(''.join(self.track.copy()))
return
digit=ord(digits[start])-ord('0')
for c in self.mapping[digit]:
self.track.append(c)
self.backtrack(digits,start+1)
self.track.pop()