掘金团队号上线,助你 Offer 临门! 点击 查看详情
前言
回顾了一下 4 月打卡历程,好像都没有刷过回溯算法类型的题目。于是我去 leetcode 上面搜了一下 回溯算法
的 tag ,找到了这一题。
题目描述
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1
不对应任何字母。
示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = ""
输出:[]
示例 3:
输入:digits = "2"
输出:["a","b","c"]
提示:
- 0 <= digits.length <= 4
- digits[i] 是范围 ['2', '9'] 的一个数字。
- 通过次数253,937提交次数449,857
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/im… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
我们可以首先建立一个 Map 来存储 数字
与 字母
之间的映射关系。然后进行 回溯
操作。
我们可以定义一个字符串表示维护当前生成的序列,以示例 1 为例,当获取到 ad
之后,此时已经遍历完号码全部数字,此时我们回退继续遍历 3 的其他字母元素,生成新的序列。换句话说本题的思路其实有点类似于用先序遍历的方式获取生成树的所有叶节点个数。
最终代码
class Solution {
static final Map<Character, String> phoneMap = Map.of(
'2', "abc", '3', "def", '4', "ghi", '5', "jkl",
'6', "mno", '7', "pqrs", '8', "tuv", '9', "wxyz"
);
public List<String> letterCombinations(String digits) {
List<String> combinations = new ArrayList<String>();
if (digits.length() == 0) {
return combinations;
}
backtrack(combinations, phoneMap, digits, 0, new StringBuffer());
return combinations;
}
public void backtrack(List<String> combinations, Map<Character, String> phoneMap, String digits, int index, StringBuffer combination) {
if (index == digits.length()) {
combinations.add(combination.toString());
} else {
char digit = digits.charAt(index);
String letters = phoneMap.get(digit);
int lettersCount = letters.length();
for (int i = 0; i < lettersCount; i++) {
combination.append(letters.charAt(i));
backtrack(combinations, phoneMap, digits, index + 1, combination);
combination.deleteCharAt(index);
}
}
}
}
结语
本题的时间复杂度是 O(3m*4n) ,因为有的数字对应的是3个字母,有的对应的是4个字母, m 和 n 分别为 3 个字母对应的数字个数和 4 个字母对应的数字个数。
本文正在参与「掘金 2021 4 月刷题打卡」, 点击查看 活动详情。喜欢的话点个赞吧。