回溯题目:电话号码的字母组合

文章目录

题目

标题和出处

标题:电话号码的字母组合

出处:17. 电话号码的字母组合

难度

4 级

题目描述

要求

给定一个仅包含数字 2-9 \texttt{2-9} 2-9 的字符串,返回该字符串能表示的所有字母组合。答案可以按任意顺序返回。

数字到字母的映射如下(与电话按键相同)。注意 1 \texttt{1} 1 不对应任何字母。

示例

示例 1:

输入: digits = "23" \texttt{digits = "23"} digits = "23"

输出: "ad","ae","af","bd","be","bf","cd","ce","cf" \texttt{"ad","ae","af","bd","be","bf","cd","ce","cf"} "ad","ae","af","bd","be","bf","cd","ce","cf"

示例 2:

输入: digits = "" \texttt{digits = ""} digits = ""

输出: \[\] \texttt{\[\]} \[\]

示例 3:

输入: digits = "2" \texttt{digits = "2"} digits = "2"

输出: "a","b","c" \texttt{"a","b","c"} "a","b","c"

数据范围

  • 0 ≤ digits.length ≤ 4 \texttt{0} \le \texttt{digits.length} \le \texttt{4} 0≤digits.length≤4
  • digitsi \texttt{digitsi} digitsi 是范围 '2', '9' \texttt{\`2', \`9'} '2', '9' 内的一个数字

解法

思路和算法

当给定的字符串 digits \textit{digits} digits 为空时,不存在可以表示的字母组合,因此返回空列表。

当给定的字符串 digits \textit{digits} digits 不为空时,由于每个数字都是 2 2 2 到 9 9 9,因此都存在对应的字母。可以使用回溯的做法得到能表示的所有字母组合。

根据数字到字母的映射,每个数字对应 3 3 3 个或 4 4 4 个可能的字母,因此首先使用哈希表存储每个数字对应的所有可能的字母,然后使用回溯得到给定的字符串能表示的所有字母组合。

回溯的过程中维护一个可变字符串用于存储当前的字母组合。每次从给定的字符串中读取一个数字并得到该数字对应的所有可能的字母,依次将每个可能的字母拼接到可变字符串的末尾。当给定的字符串遍历结束时,可变字符串即为一个可能的字母组合,将该字母组合添加到结果列表中,然后回退并遍历其他可能的字母。

当给定的字符串中的每个数字对应的所有可能的字母都遍历结束时,即可得到给定的字符串能表示的所有字母组合。

实现方面,由于每个数字都是 2 2 2 到 9 9 9,因此可以使用字符串数组代替哈希表存储每个数字对应的字母,可变字符串使用 StringBuffer \texttt{StringBuffer} StringBuffer 或 StringBuilder \texttt{StringBuilder} StringBuilder 类型的对象。

代码

java 复制代码
class Solution {
    static String[] lettersArr = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    String digits;
    List<String> combinations;

    public List<String> letterCombinations(String digits) {
        this.digits = digits;
        this.combinations = new ArrayList<String>();
        if (digits.length() == 0) {
            return combinations;
        }
        backtrack(0, new StringBuffer());
        return combinations;
    }

    public void backtrack(int index, StringBuffer combination) {
        if (index == digits.length()) {
            combinations.add(combination.toString());
        } else {
            int digit = digits.charAt(index) - '0';
            String letters = lettersArr[digit];
            int lettersCount = letters.length();
            for (int i = 0; i < lettersCount; i++) {
                combination.append(letters.charAt(i));
                backtrack(index + 1, combination);
                combination.deleteCharAt(index);
            }
        }
    }
}

复杂度分析

  • 时间复杂度: O ( 3 m × 4 n × ( m + n ) + ∣ Σ ∣ ) O(3^m \times 4^n \times (m + n) + |\Sigma|) O(3m×4n×(m+n)+∣Σ∣),其中 m m m 和 n n n 分别是字符串 digits \textit{digits} digits 中的对应 3 3 3 个字母的数字个数和对应 4 4 4 个字母的数字个数, Σ \Sigma Σ 是数字集合,这道题中 ∣ Σ ∣ = 8 |\Sigma| = 8 ∣Σ∣=8。初始化哈希表需要 O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣) 的时间,字符串 digits \textit{digits} digits 的长度是 m + n m + n m+n,能表示的所有字母组合数是 3 m × 4 n 3^m \times 4^n 3m×4n,需要遍历每一种字母组合,对于每一种字母组合需要 O ( m + n ) O(m + n) O(m+n) 的时间添加到答案中,因此时间复杂度是 O ( 3 m × 4 n × ( m + n ) + ∣ Σ ∣ ) O(3^m \times 4^n \times (m + n) + |\Sigma|) O(3m×4n×(m+n)+∣Σ∣)。

  • 空间复杂度: O ( m + n + ∣ Σ ∣ ) O(m + n + |\Sigma|) O(m+n+∣Σ∣),其中 m m m 和 n n n 分别是字符串 digits \textit{digits} digits 中的对应 3 3 3 个字母的数字个数和对应 4 4 4 个字母的数字个数, Σ \Sigma Σ 是数字集合,这道题中 ∣ Σ ∣ = 8 |\Sigma| = 8 ∣Σ∣=8。字符串 digits \textit{digits} digits 的长度是 m + n m + n m+n,存储字母组合的可变字符串和递归调用栈需要 O ( m + n ) O(m + n) O(m+n) 的空间,哈希表需要 O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣) 的空间。

相关推荐
z2005093019 天前
今日算法(带回文问题的回溯)
算法·leetcode·回溯
每天回答3个问题1 个月前
LeetCodeHot100|回溯算法、46.全排列、78.子集、17.电话号码的字母组合
算法·深度优先·回溯
superior tigre2 个月前
78 子集
算法·leetcode·深度优先·回溯
kronos.荒2 个月前
非递减序列(python)
python·回溯
kronos.荒2 个月前
回溯(python)
python·回溯
kronos.荒2 个月前
N皇后问题(python)
python·回溯
kronos.荒2 个月前
全排列2(重复元素去重、python)
python·回溯
W23035765732 个月前
0-1 背包进阶:回溯法(子集树)+ 分支限界优化 极致详解(C++ 完整实现)
动态规划·回溯·算法设计·0-1背包
语戚2 个月前
力扣 494. 目标和 —— 回溯 & 动态规划双解法全解(Java 实现)
java·算法·leetcode·动态规划·力扣·dp·回溯