返回

理解 LeetCode 17. 电话号码的字母组合——探索数字与字母的奇妙关联

后端

引言

在计算机科学领域,数字和字母之间存在着密切的联系。这种联系体现在各种数据结构和算法中,例如数字与字母的映射关系。LeetCode 17. 电话号码的字母组合正是这样一个经典问题,它要求我们根据数字与字母的映射关系,生成所有可能的字母组合。

问题

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

给出数字到字母的映射如下:

2 -> "abc"
3 -> "def"
4 -> "ghi"
5 -> "jkl"
6 -> "mno"
7 -> "pqrs"
8 -> "tuv"
9 -> "wxyz"

思路与实现

这个问题可以采用递归或回溯算法来解决。

递归算法

def letterCombinations(digits):
    if not digits:
        return []

    # 创建一个字典来存储数字与字母的映射关系
    mapping = {
        "2": "abc",
        "3": "def",
        "4": "ghi",
        "5": "jkl",
        "6": "mno",
        "7": "pqrs",
        "8": "tuv",
        "9": "wxyz",
    }

    # 创建一个列表来存储结果
    result = []

    # 递归函数
    def backtrack(index, combination):
        # 如果已经到达字符串的末尾,则将组合添加到结果列表中
        if index == len(digits):
            result.append(combination)
            return

        # 获取当前数字对应的字母
        letters = mapping[digits[index]]

        # 遍历当前数字对应的所有字母
        for letter in letters:
            # 将当前字母添加到组合中
            combination += letter

            # 递归调用函数,处理下一个数字
            backtrack(index + 1, combination)

            # 将当前字母从组合中移除
            combination = combination[:-1]

    # 调用递归函数
    backtrack(0, "")

    # 返回结果
    return result

回溯算法

def letterCombinations(digits):
    if not digits:
        return []

    # 创建一个字典来存储数字与字母的映射关系
    mapping = {
        "2": "abc",
        "3": "def",
        "4": "ghi",
        "5": "jkl",
        "6": "mno",
        "7": "pqrs",
        "8": "tuv",
        "9": "wxyz",
    }

    # 创建一个栈来存储组合
    stack = []

    # 创建一个结果列表
    result = []

    # 遍历数字字符串
    for digit in digits:
        # 获取当前数字对应的字母
        letters = mapping[digit]

        # 如果栈为空,则将当前数字对应的字母添加到栈中
        if not stack:
            for letter in letters:
                stack.append(letter)
        # 如果栈不为空,则将当前数字对应的字母与栈中的组合进行组合,并添加到栈中
        else:
            temp = []
            while stack:
                combination = stack.pop()
                for letter in letters:
                    temp.append(combination + letter)
            stack = temp

    # 将栈中的组合添加到结果列表中
    while stack:
        result.append(stack.pop())

    # 返回结果
    return result

复杂度分析

  • 时间复杂度:O(3^n * 4^m),其中 n 是数字字符串的长度,m 是数字字符串中数字 7、8、9 的数量。
  • 空间复杂度:O(3^n * 4^m),其中 n 是数字字符串的长度,m 是数字字符串中数字 7、8、9 的数量。

结语

LeetCode 17. 电话号码的字母组合是一个经典的问题,它要求我们根据数字与字母的映射关系,生成所有可能的字母组合。通过本文的讲解,您应该已经对这个问题有了深入的理解。如果您想进一步提高自己的编程能力,可以尝试自己实现这个问题,并与本文中的解法进行比较。