当前位置:   article > 正文

代码随想录算法训练营Day25 | 216.组合总和III、17.电话号码的字母组合 | Python | 个人记录向

代码随想录算法训练营Day25 | 216.组合总和III、17.电话号码的字母组合 | Python | 个人记录向

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

看文章

思路类似,只是实际实现不一样,代码如下:

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()  # 回溯
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

时间复杂度: O(n * 2^n)
空间复杂度: O(n)

17.电话号码的字母组合

代码随想录:17.电话号码的字母组合
Leetcode:17.电话号码的字母组合

做题

无思路。

看文章

回溯法可解决n个for循环问题。
回溯三部曲:

  1. 确定回溯参数
  2. 确定终止条件
  3. 确定单层遍历逻辑

面试代码最好考虑特殊情况(在本题中为输入错误,输入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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

时间复杂度: O(3^m * 4^n),其中 m 是对应四个字母的数字个数,n 是对应三个字母的数字个数
空间复杂度: O(3^m * 4^n)

以往忽略的知识点小结

  • 回溯法基本流程还是不熟,文章里讲逻辑的模块都是C++,之前就没太捋逻辑,但实际上也很简单,回溯三部曲为:
    1. 确定回溯参数
    2. 确定终止条件
    3. 确定单层遍历逻辑
  • 字符增减的处理:在末尾增加1个字符为 s += letter,在末尾减少1个字符为s = s[ : -1]

个人体会

完成时间:1h20min。
心得:回溯法、字符处理还需要熟悉。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/500926
推荐阅读
相关标签
  

闽ICP备14008679号