代码随想录算法营Day28 | 77.组合,216.组合总和III,17.电话号码的字母组合

77.组合

这题就是典型的回溯算法思路,具体实现如下。

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        subset = []
        res = []
        def backTrack(start):
            if len(subset) == k:
                res.append(subset[:])
                return
            for i in range(start,n+1):
                subset.append(i)
                backTrack(i+1)
                subset.pop()
        backTrack(1)
        return res

不过我们可以通过要求的subset长度做一些剪枝操作。正常来说在for循环的时候我们需要从startIndex遍历到n,但如果我们选择的startIndex到n的元素已经不足以填充subset去满足k个长度,那么我们就没有必要再对接下来的元素进行遍历。for循环中优化之后的代码如下。

            for i in range(start,n-(k-len(subset))+2):
                subset.append(i)
                backTrack(i+1)
                subset.pop()

216.组合总和III

这题思路与上题类似。

class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        subset = []
        res = []
        def backTrack(start,s):
            if s > n:
                return
            if len(subset) == k and s == n:
                res.append(subset[:])
                return
            for i in range(start,10 - (k - len(subset)) + 1):
                subset.append(i)
                backTrack(i+1,s+i)
                subset.pop()
        backTrack(1,0)
        return res

17.电话号码的字母组合

这题先用个map或者数组来做个数字与字母的映射,然后遍历digits中的每个字符,穷举所有可能的组合。

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if len(digits) == 0:
            return []
        m = {"2":"abc","3":"def","4":"ghi","5":"jkl",
            "6":"mno","7":"pqrs","8":"tuv","9":"wxyz"}
        path = []
        res = []
        def backTrack(index):
            if index == len(digits):
                res.append("".join(path))
                return
            for i in m[digits[index]]:
                path.append(i)
                backTrack(index+1)
                path.pop()
        backTrack(0)
        return res

你可能感兴趣的:(算法,python,leetcode)