秋招算法备战第25天 | 216.组合总和III、17.电话号码的字母组合

216. 组合总和 III - 力扣(LeetCode)

根据回溯的模板写出来了,并且加上了剪枝

class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        result = []
        path = []

        def backtracking(start, cur_sum, depth):
            if cur_sum > n:
                return
            if depth == k:
                if cur_sum == n:
                    result.append(path[:])
                return 
            
            for i in range(start, 10):
                path.append(i)
                backtracking(i+1, cur_sum+i, depth+1)
                path.pop()
        
        backtracking(1, 0, 0)
        return result

参考代码如下,发现在循环的时候还额外加了个剪枝操作

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()  # 回溯

17. 电话号码的字母组合 - 力扣(LeetCode)

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if len(digits) == 0:
            return []
        
        map_dict = {
            '2':['a', 'b', 'c'], 
            '3': ['d', 'e', 'f'], 
            '4': ['g', 'h', 'i'], 
            '5': ['j', 'k', 'l'], 
            '6': ['m', 'n', 'o'], 
            '7': ['p', 'q', 'r', 's'], 
            '8': ['t', 'u', 'v'], 
            '9': ['w', 'x', 'y', 'z']
        }
        result = []
        path = []

        def backtracking(depth):
            if len(path) == len(digits):
                result.append(''.join(path))
                return
            
            chars = map_dict[str(digits[depth])]
            for char in chars:
                path.append(char)
                backtracking(depth+1)
                path.pop()
        
        backtracking(0)
        return result

总结

跟着回溯的模板写会比较清晰,其本质就是穷举,所以一般需要在终止和循环处加一些剪枝操作用来减少对不必要情况的处理

你可能感兴趣的:(算法,python,开发语言)