力扣-电话号码组合

17. 电话号码的字母组合 - 力扣(LeetCode)

问题分析

给定一个仅包含数字 2-9 的字符串,我们需要生成所有可能的字母组合,其中每个数字映射到一组字母(类似于电话按键)。例如:

  • 数字 "2" 映射到字母 "a", "b", "c"
  • 数字 "3" 映射到字母 "d", "e", "f"
  • 以此类推(数字 1 忽略,因为它不对应任何字母)。

这是一个组合生成问题,我们需要为输入字符串中的每个数字位置选择对应的字母,并生成所有可能的序列。例如,输入 "23",可能的组合有 "ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"。

算法思路

为了解决这个问题,我们可以使用回溯算法(backtracking)。回溯是一种通过递归探索所有可能路径的方法,并在达到终点时记录结果。思路如下:

  1. 映射定义:首先,定义一个数字到字母的映射表(例如,使用数组或映射表存储每个数字对应的字符串)。
  2. 递归回溯 :从输入字符串的第一个字符开始,对于每个数字:
    • 获取该数字对应的所有字母。
    • 遍历每个字母,将其添加到当前组合中。
    • 递归处理下一个数字位置。
    • 当处理完所有数字时,将当前组合添加到结果列表。
    • 回溯:在递归返回后,移除最后添加的字母,以便尝试其他字母。
  3. 基准情况:当所有数字处理完毕时(当前索引等于字符串长度),保存当前组合。
  4. 结果返回:递归结束后,返回所有生成的组合列表。

这种方法的时间复杂度为 O(3ᴺ × 4ᴹ) ,其中 N 是映射到 3 个字母的数字个数,M 是映射到 4 个字母的数字个数(例如数字 7 和 9)。空间复杂度为 O() L是组合长度,主要用于递归栈和结果存储。

实现过程

我们将使用 Java 实现上述思路。步骤如下:

  1. 定义映射表 :使用一个字符串数组 mapping,索引对应数字字符(例如,索引 2 存储 "abc")。
  2. 主方法letterCombinations 方法接受输入字符串 digits。如果输入为空或 null,直接返回空列表。
  3. 回溯方法 :定义一个递归方法 backtrack,参数包括:
    • currentCombination:当前构建的组合(使用 StringBuilder 以高效修改)。
    • index:当前处理的数字在输入字符串中的索引。
    • digits:输入字符串。
    • mapping:映射表。
    • result:存储结果的列表。
  4. 递归逻辑
    • 基准情况:如果 index 等于 digits.length(),说明所有数字处理完毕,将当前组合添加到 result
    • 否则,获取当前数字对应的字母字符串。
    • 遍历每个字母:
      • 将字母添加到 currentCombination
      • 递归调用 backtrack 处理下一个索引(index + 1)。
      • 回溯:移除 currentCombination 的最后一个字母,以便尝试下一个字母。
  5. 结果返回:初始化结果列表,调用回溯方法,返回结果。

下面是完整的 Java 实现代码:

java 复制代码
import java.util.ArrayList;
import java.util.List;

class Solution {  // 必须使用 Solution 类名
    public List<String> letterCombinations(String digits) {
        // 如果输入为空,返回空列表
        if (digits == null || digits.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 定义数字到字母的映射表:索引对应数字字符('2' 到 '9')
        String[] mapping = {
            "",     // 索引 0
            "",     // 索引 1(数字 1 无映射)
            "abc",  // 索引 2(数字 2)
            "def",  // 索引 3(数字 3)
            "ghi",  // 索引 4(数字 4)
            "jkl",  // 索引 5(数字 5)
            "mno",  // 索引 6(数字 6)
            "pqrs", // 索引 7(数字 7)
            "tuv",  // 索引 8(数字 8) ← 修正这里!
            "wxyz"  // 索引 9(数字 9)
        };
        
        // 存储结果的列表
        List<String> result = new ArrayList<>();
        // 使用 StringBuilder 构建组合
        StringBuilder currentCombination = new StringBuilder();
        // 从索引 0 开始回溯
        backtrack(currentCombination, 0, digits, mapping, result);
        return result;
    }
    
    private void backtrack(StringBuilder currentCombination, int index, 
                           String digits, String[] mapping, List<String> result) {
        // 基准情况:所有数字处理完毕
        if (index == digits.length()) {
            result.add(currentCombination.toString());
            return;
        }
        
        // 获取当前数字对应的字母
        char digit = digits.charAt(index);
        String letters = mapping[digit - '0'];
        
        // 遍历当前数字对应的每个字母
        for (char letter : letters.toCharArray()) {
            currentCombination.append(letter);  // 添加字母
            backtrack(currentCombination, index + 1, digits, mapping, result);
            currentCombination.deleteCharAt(currentCombination.length() - 1);  // 回溯
        }
    }
}

代码解释

  • 映射表mapping 数组存储了数字 0-9 的字母映射,其中索引 0 和 1 为空(因为数字 1 无映射)。
  • 回溯方法backtrack 使用递归生成组合。StringBuilder 用于高效构建和修改字符串。
  • 回溯关键 :在遍历字母后,调用递归前添加字母,递归后移除字母(deleteCharAt),这确保了在尝试其他路径时组合状态正确。
  • 效率:这种方法避免了重复计算,递归深度等于输入字符串长度,适合小规模输入(LeetCode 测试用例通常较小)。

您可以调用 letterCombinations 方法测试不同输入,例如:

  • 输入 "23" 返回 ["ad","ae","af","bd","be","bf","cd","ce","cf"]
  • 输入 "" 返回空列表。

这个实现符合问题要求,并高效地生成了所有字母组合。

相关推荐
xunyan62341 小时前
面向对象(下)-模版方法的设计模式其应用场景
java·学习·设计模式
Yweir1 小时前
Linux性能监控的工具集和分析命令工具
java·linux·jvm
Dxxyyyy1 小时前
零基础学JAVA--Day41(IO文件流+IO流原理+InputStream+OutputStream)
java·开发语言·python
狗头实习生1 小时前
电话号码字母组合
java·算法·leetcode
C雨后彩虹1 小时前
矩阵扩散问题
java·数据结构·算法·华为·面试
独自破碎E1 小时前
力场重叠问题
java·开发语言·算法
free-elcmacom1 小时前
机器学习入门<5>支持向量机形象教学:寻找最安全的“三八线”,人人都能懂的算法核心
人工智能·python·算法·机器学习·支持向量机
组合缺一1 小时前
Solon AI 开发学习16 - generate - 生成模型(图、音、视)
java·人工智能·学习·ai·llm·solon
谷哥的小弟1 小时前
Spring Framework源码解析——AnnotationAwareOrderComparator
java·后端·spring·源码