(python刷题)leetcode 第17题:电话号码的字母组合

题目在leetcode上的链接为:
https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/

题目描述
在这里插入图片描述

解题思路
这是一个排序组合的问题,可以使用回溯法的思想解题。
回溯法的思想是先自上到下,然后再一步步从下往上进行回溯。对于一个有多种解的问题,回溯法先按照其中的一种解法往最底层执行,执行完毕后再回到上一层执行下一种解法,知道找到所有满足条件的解。
在这一题中,我们构建一个回溯函数 backtrack(combination, nextdigits),combination 表示当前的字母组合,nextdigitis 表示接下来需要传入的数字,算法一次性传入一个数字,然后将这个数字对应的字母 letter 添加到组合中,即得到的组合为 combination + letter,直到不需要再有数字传入,则得到了所有的字母组合。

算法的步骤为:

  • 建立一个数字与对应字母的映射的字典
  • 初始化 combination=’’,建立回溯函数 backtrack(combination, nextdigits):
    • 如果 nextdigits 的长度为0,说明接下来没有数字传入,得到了一种字母组合
    • 否则,循环遍历传入的第一个数字 nextdigits[0] 对应的字母 letter:
      • 将字母添加到当前组合中,并继续回溯下去,即 backtrack(combination+letter, nextdigits[1:])

下面以题目中传入的数字 “23” 为例说明算法的执行步骤。
在这里插入图片描述
如上图所示,

  • 首先传入的第一个数字为 ‘2’,使用循环遍历 ‘2’ 对应的字母依次为 ‘a’,‘b’,‘c’
  • 在上面的第一次循环中,接下来继续执行 backtrack(combination+letter, nextdigits[1:]) 具体参数为 backtrack(’’ + ‘a’, ‘3’),传入的数字为 ‘3’,使用循环遍历 ‘3’ 对应的字母依次为 ‘d’,‘e’,‘f’。
  • 在上面的第一次循环中,接下来继续执行 backtrack(combination+letter, nextdigits[1:]) 具体参数为 backtrack(‘a’ + ‘d’, ‘’),此时 combination=‘ad’,没有可传入的数字,因此就得到了第一种组合 ‘ad’,backtrack(‘a’ + ‘d’, ‘’) 执行完毕。
  • 返回上一层函数 backtrack(’’ + ‘a’, ‘3’),继续执行循环的第二步,即 backtrack(‘a’ + ‘e’, ‘’)…直到所有组合都找到为止

可以看到回溯算法执行的步骤类似于树的深度优先搜索,对于数字 ‘23’,首先找到的第一个组合为 ‘ad’,然后回溯到上一层,继续执行找到 ‘ae’,然后接下来依次是 ‘af’,‘bd’,‘be’,‘bf’…

复杂度分析:
算法的时间复杂度为所有排序组合的数目,即 o ( 3 m 4 n ) o(3^m4^n) ,在给定的数字字符串中,m 为对应三个字母的数字个数,n 为对应四个字母的数字个数
由于需要创建列表储存所有排序组合的结果,所以空间复杂度为 o ( 3 m 4 n ) o(3^m4^n)

python代码

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        phone = {
            '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']
        }
        def backtrack(combination, nextdigits):
            if len(nextdigits) == 0:
                output.append(combination)
            else:
                for letter in phone[nextdigits[0]]:
                    backtrack(combination + letter, nextdigits[1:])
        
        output = []
        if not digits:
            return []
        backtrack('', digits)

        return output

参考资料:
https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/solution/dian-hua-hao-ma-de-zi-mu-zu-he-by-leetcode/
https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/solution/leetcode-17-letter-combinations-of-a-phone-number-/

发布了37 篇原创文章 · 获赞 6 · 访问量 5383

猜你喜欢

转载自blog.csdn.net/qq_37891889/article/details/104339819