目录
216.组合总和 III
如果把 组合问题理解了,本题就容易一些了。题目链接/文章讲解:代码随想录
视频讲解:和组合问题有啥区别?回溯算法如何剪枝?| LeetCode:216.组合总和III_哔哩哔哩_bilibili
思路
强烈建议看看我上一篇里面的基础介绍,我觉得Carl哥说的很对,回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。
就是一位一位数来判断,每一位的取值用的是for循环,然后在for循环里面嵌套递归函数,遍历下一层。
代码
class Solution:
def combinationSum3(self, k: int, n: int) -> List[List[int]]:
res = []
self.backtracking(n, k, 0, 1, [], res)
return res
def backtracking(self, targetsum, k, currentsum, startIndex, chosen, res):
if currentsum > targetsum:
return
if len(chosen) == k:
if currentsum == targetsum:
res.append(chosen[:])
return
for i in range(startIndex, 9 - (k - len(chosen)) + 2): # 剪枝 假如可以田3位,第一位最高只能到7,因为后面还有两位要填
currentsum += i # 处理
chosen.append(i) # 处理
self.backtracking(targetsum, k, currentsum, i + 1, chosen, res) # 递归到下一层
currentsum -= i # 回溯
chosen.pop() # 回溯
有没有发现backtracking()函数里的for循环的右区间 9-(k-len(chosen)+2(每日嘻嘻1/1),不理解的去看我的上一条博客,里面我解释了怎么推导的,再不懂可以看上条博客里的链接。
17.电话号码的数字组合
本题大家刚开始做会有点难度,先自己思考20min,没思路就直接看题解。题目链接/文章讲解:代码随想录
思路
深入本质,一通百通(初中数学老师说的)
组合类的题目都差不多的,无非现在一个电话按钮上有多个字母,把数据集,res列表和chosen列表放到__init__(self)初始化函数里。大伙看代码应该能看懂。
代码
from typing import List
class Solution:
def __init__(self):
self.res = []
self.chosen = ""
self.data_set = ["", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"]
def letterCombinations(self, digits: str) -> List[str]:
if len(digits) == 0:
return self.res
self.backtracking(digits, 0)
return self.res
def backtracking(self, digits, index):
if index == len(digits):
self.res.append(self.chosen)
return
digit = int(digits[index])
letter = self.data_set[digit]
for i in letter:
self.chosen += i
self.backtracking(digits, index + 1)
self.chosen = self.chosen[:-1]