216.组合总和III
代码随想录:216.组合总和III
Leetcode:216.组合总和III
做题
参照着Day24中77.组合的结构,调试后AC了,代码如下:
class Solution:
def combinationSum3(self, k: int, n: int) -> List[List[int]]:
self.res = []
self.backtracking(k, n, 1, [])
return self.res
def backtracking(self, k, target, start, path):
if target == 0 and len(path) == k:
self.res.append(path[:])
elif target != 0 and len(path) == k:
return
for i in range(start, 10):
if target - i >= 0:
target -= i
path.append(i)
else:
return
self.backtracking(k, target, i+1, path)
path.pop()
target += i
看文章
思路类似,只是实际实现不一样,代码如下:
class Solution:
def combinationSum3(self, k: int, n: int) -> List[List[int]]:
result = [] # 存放结果集
self.backtracking(n, k, 0, 1, [], result)
return result
def backtracking(self, targetSum, k, currentSum, startIndex, path, result):
if currentSum > targetSum: # 剪枝操作
return # 如果path的长度等于k但currentSum不等于targetSum,则直接返回
if len(path) == k:
if currentSum == targetSum:
result.append(path[:])
return
for i in range(startIndex, 9 - (k - len(path)) + 2): # 剪枝
currentSum += i # 处理
path.append(i) # 处理
self.backtracking(targetSum, k, currentSum, i + 1, path, result) # 注意i+1调整startIndex
currentSum -= i # 回溯
path.pop() # 回溯
时间复杂度: O(n * 2^n)
空间复杂度: O(n)
17.电话号码的字母组合
代码随想录:17.电话号码的字母组合
Leetcode:17.电话号码的字母组合
做题
无思路。
看文章
回溯法可解决n个for循环问题。
回溯三部曲:
- 确定回溯参数
- 确定终止条件
- 确定单层遍历逻辑
面试代码最好考虑特殊情况(在本题中为输入错误,输入0、1、#等)。
具体代码如下:
class Solution:
def __init__(self):
self.letterMap = [
"", # 0
"", # 1
"abc", # 2
"def", # 3
"ghi", # 4
"jkl", # 5
"mno", # 6
"pqrs", # 7
"tuv", # 8
"wxyz" # 9
]
self.result = []
self.s = ""
def backtracking(self, digits, index):
if index == len(digits):
self.result.append(self.s)
return
digit = int(digits[index]) # 将索引处的数字转换为整数
letters = self.letterMap[digit] # 获取对应的字符集
for i in range(len(letters)):
self.s += letters[i] # 处理字符
self.backtracking(digits, index + 1) # 递归调用,注意索引加1,处理下一个数字
self.s = self.s[:-1] # 回溯,删除最后添加的字符
def letterCombinations(self, digits):
if len(digits) == 0:
return self.result
self.backtracking(digits, 0)
return self.result
时间复杂度: O(3^m * 4^n),其中 m 是对应四个字母的数字个数,n 是对应三个字母的数字个数
空间复杂度: O(3^m * 4^n)
以往忽略的知识点小结
- 回溯法基本流程还是不熟,文章里讲逻辑的模块都是C++,之前就没太捋逻辑,但实际上也很简单,回溯三部曲为:
- 确定回溯参数
- 确定终止条件
- 确定单层遍历逻辑
- 字符增减的处理:在末尾增加1个字符为 s += letter,在末尾减少1个字符为s = s[ : -1]
个人体会
完成时间:1h20min。
心得:回溯法、字符处理还需要熟悉。