0017. 电话号码的字母组合

题目地址(17. 电话号码的字母组合)

https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number

题目描述

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

image.png

前置知识

  • 回溯

  • 笛卡尔积

公司

  • 阿里

  • 百度

  • 字节

  • 腾讯

回溯

思路

由于要求所有的可能性,因此考虑使用回溯法进行求解。回溯是一种通过穷举所有可能情况来找到所有解的算法。如果一个候选解最后被发现并不是可行解,回溯算法会舍弃它,并在前面的一些步骤做出一些修改,并重新尝试找到可行解。究其本质,其实就是枚举。

如果没有更多的数字需要被输入,说明当前的组合已经产生。

如果还有数字需要被输入:

  • 遍历下一个数字所对应的所有映射的字母

  • 将当前的字母添加到组合最后,也就是 str + tmp[r]

关键点

  • 回溯

  • 回溯模板

代码

  • 语言支持:JS, C++, Java, Python

JavaScript Code:

C++ Code:

Java Code:

Python Code:

复杂度分析

N + M 是输入数字的总数

  • 时间复杂度:O(2^N),其中 N 为 digits 对于的所有可能的字母的和。

  • 空间复杂度:O(2^N),其中 N 为 digits 对于的所有可能的字母的和。

笛卡尔积

思路

不难发现, 题目要求的是一个笛卡尔积。

比如 digits = 'ab',其实就是 a 对应的集合 {'a', 'b', 'c'} 和 b 对应的集合 {'d', 'e', 'f'} 笛卡尔积。

简单回忆一下笛卡尔积的内容。对于两个集合 A 和 B,A×B = {(x,y)|x∈A∧y∈B}。

例如,A={a,b}, B={0,1,2},则:

  • A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}

  • B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}

实际上,力扣关于笛卡尔积优化的题目并不少。 比如:

知道了这一点之后,就不难写出如下代码。

由于我们使用了笛卡尔积优化, 因此可以改造成纯函数,进而使用记忆化递归,进一步降低时间复杂度, 这是一个常见的优化技巧。

关键点

  • 笛卡尔积

  • 记忆化递归

代码

代码支持:Python3

复杂度分析

N + M 是输入数字的总数

  • 时间复杂度:O(N^2),其中 N 为 digits 对于的所有可能的字母的和。

  • 空间复杂度:O(N^2),其中 N 为 digits 对于的所有可能的字母的和。

大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。 大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。

最后更新于

这有帮助吗?