代码随想录算法训练营第二十五天| 216.组合总和III 17.电话号码的字母组合

文档讲解:代码随想录

视频讲解:代码随想录B站账号

状态:看了视频题解和文章解析后做出来了

 216.组合总和III

class Solution:
    def backtracking(self, k, n, path, result, startindex):
        if sum(path) > n:
            return
        if len(path) == k:
            if sum(path) == n:
                result.append(path[:])
            return

        for i in range(startindex, 9 - (k - len(path)) + 2):
            path.append(i)
            self.backtracking(k, n, path, result, i+1)
            path.pop()

        return result

    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        res = self.backtracking(k, n, [], [], 1)

        return res

思路:这题和昨天的组合题非常类似,所以没看题解自己就做出来了。

回溯三部曲:

第一步:确定函数参数。k和n是题目的input必须要传入,path为当前的组合状态,用于终止条件的判断上,result是最后返回的结果集,startindex确保了每个元素只使用一遍且不会有重复的组合出现。

第二步:确定终止条件。当path的长度等于k的时候终止,这里还需加一个if判断,如果path的总和等于k才把path加入到result结果集中,不然直接return。

第三步:确定单层递归逻辑。同样是先在path中append当前遍历的元素,然后backtracking使得startindex+1,最后pop进行回溯。

- 剪枝1:如果path的总和已经大于目标n,直接返回。

- 剪枝2:for循环的终止元素的长度必须大于等于k-len(path)。

剪枝详情如下图:

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

 空间复杂度: O(n)

17.电话号码的字母组合

class Solution:
    def backtracking(self, digits, path, result, mapping, startindex1):
        if len(path) == len(digits):
            result.append(''.join(path[:]))

        for i in range(startindex1, len(digits)):
            for j in range(len(mapping[digits[i]])):
                path.append(mapping[digits[i]][j])
                self.backtracking(digits, path, result, mapping, i+1)
                path.pop()

        return result

    def letterCombinations(self, digits: str) -> List[str]:
        if digits == '':
            return []

        mapping = {
            '0':"",     # 0
            '1':"",     # 1
            '2':"abc",  # 2
            '3':"def",  # 3
            '4':"ghi",  # 4
            '5':"jkl",  # 5
            '6':"mno",  # 6
            '7':"pqrs", # 7
            '8':"tuv",  # 8
            '9':"wxyz"  # 9
        }
        res = self.backtracking(digits, [], [], mapping, 0)
        return res

 思路:又是一道独立完成的题目,难道我很适合回溯?

1. 确定函数参数:digits为题目input,path和result哼哈二人组,mapping用于将数字转化为对应的字母,startindex保证无重复。

2. 确定终止条件:当path的长度等digits的长度,终止并append入结果集。

3. 确定单层递归逻辑:两个for循环,第一个循环从startindex开始遍历到digits长度,确保每个元素都被遍历到。第二个for循环遍历当前元素对应的字母表,所以range为len(mapping[digits[i]]). 这里不可以hardcoding为3,因为不同数字对应的字符串长度不同。

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

 空间复杂度: O(3^m * 4^n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值