【LeetCode】17.电话号码的字母组合

欢迎来到李耶的频道【LeetCode面试题】。


电话号码的字母组合

17.电话号码的字母组合

题目

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

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

复制代码
2: "abc"
3: "def"
4: "ghi"
5: "jkl"
6: "mno"
7: "pqrs"
8: "tuv"
9: "wxyz"

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

输入:digits = ""
输出:[]

输入:digits = "2"
输出:["a","b","c"]

解法一:回溯法(DFS)

思路:使用深度优先搜索(DFS)遍历所有可能的组合。维护一个路径字符串,每次递归选择一个数字对应的一个字母,直到处理完所有数字。

javascript 复制代码
function letterCombinations(digits) {
  if (!digits || digits.length === 0) return [];
  
  const map = {
    '2': 'abc',
    '3': 'def',
    '4': 'ghi',
    '5': 'jkl',
    '6': 'mno',
    '7': 'pqrs',
    '8': 'tuv',
    '9': 'wxyz'
  };
  
  const result = [];
  
  function backtrack(index, path) {
    if (index === digits.length) {
      result.push(path);
      return;
    }
    
    const letters = map[digits[index]];
    for (const letter of letters) {
      backtrack(index + 1, path + letter);
    }
  }
  
  backtrack(0, '');
  return result;
}
  • 时间复杂度 / 空间复杂度:O(3^m × 4^n) / O(m + n),其中 m 是 3 个字母的数字个数,n 是 4 个字母的数字个数
  • 优势:经典回溯模板,逻辑清晰,是面试中最推荐的写法

解法二:队列法(BFS)

思路:使用队列进行广度优先搜索(BFS)。初始队列为空字符串,逐个处理每个数字,对于队列中每个已有组合,扩展当前数字对应的所有字母。

javascript 复制代码
function letterCombinations(digits) {
  if (!digits || digits.length === 0) return [];
  
  const map = {
    '2': 'abc',
    '3': 'def',
    '4': 'ghi',
    '5': 'jkl',
    '6': 'mno',
    '7': 'pqrs',
    '8': 'tuv',
    '9': 'wxyz'
  };
  
  let queue = [''];
  
  for (const digit of digits) {
    const letters = map[digit];
    const newQueue = [];
    for (const prefix of queue) {
      for (const letter of letters) {
        newQueue.push(prefix + letter);
      }
    }
    queue = newQueue;
  }
  
  return queue;
}
  • 时间复杂度 / 空间复杂度:O(3^m × 4^n) / O(3^m × 4^n)
  • 优势:BFS 思路,适合理解不同的遍历方式
  • 劣势:需要存储中间结果,空间占用略大

解法三:迭代法(循环拼接)

思路:使用循环逐个数字处理,每次用当前结果集与当前数字对应的字母列表进行笛卡尔积拼接,生成新的结果集。

javascript 复制代码
function letterCombinations(digits) {
  if (!digits || digits.length === 0) return [];
  
  const map = {
    '2': 'abc',
    '3': 'def',
    '4': 'ghi',
    '5': 'jkl',
    '6': 'mno',
    '7': 'pqrs',
    '8': 'tuv',
    '9': 'wxyz'
  };
  
  let result = [''];
  
  for (const digit of digits) {
    const letters = map[digit];
    const newResult = [];
    for (const prefix of result) {
      for (const letter of letters) {
        newResult.push(prefix + letter);
      }
    }
    result = newResult;
  }
  
  return result;
}
  • 时间复杂度 / 空间复杂度:O(3^m × 4^n) / O(3^m × 4^n)
  • 优势:代码简洁,与 BFS 本质相同
  • 劣势:与 BFS 类似,空间占用略大

解法对比

解法 时间 / 空间复杂度 优势 推荐指数
回溯法(DFS) O(3^m × 4^n) / O(m + n) 递归经典,空间最优 ⭐⭐⭐⭐⭐
队列法(BFS) O(3^m × 4^n) / O(3^m × 4^n) BFS 思路,易于理解 ⭐⭐⭐⭐
迭代法 O(3^m × 4^n) / O(3^m × 4^n) 代码简洁,无需递归 ⭐⭐⭐⭐

扩展题

  1. 括号生成 :给定 n 对括号,生成所有由 n 对括号组成的有效组合。
  2. 组合总和:给定一个无重复元素的数组和一个目标数,找出所有可以使数字和等于目标数的组合。
  3. 子集:给定一个整数数组,返回该数组所有可能的子集(幂集)。

"他山之石,可以攻玉。" ------ 《诗经·小雅·鹤鸣》

关注李耶,每天一道面试题,一起卷起来 🔥

相关推荐
不会就选b8 小时前
算法日常・每日刷题--<动态规划>19
算法·leetcode·职场和发展
考研保研资料分享8 小时前
新闻传播保研经验:中传预推免面试、广告学代表作与实习准备(2025)
面试·职场和发展
没有钱的钱仔9 小时前
协方差矩阵含义
算法·机器学习·矩阵
垆边人似月.9 小时前
华为机试题 :和为 K 的子数组个数
算法·leetcode·华为
三*一9 小时前
优化修整算法
前端·javascript·算法
达子66610 小时前
RUST 图解 第 3 章:通用编程概念(Common Programming Concepts)
开发语言·算法·rust
夏幻灵10 小时前
每日一题:LeetCode 165:比较版本号
算法·leetcode·职场和发展
道尔柯南10 小时前
C++ 面向对象编程入门:类和对象(上)
开发语言·c++·算法
Navigator_Z10 小时前
LeetCode //C - 1288. Remove Covered Intervals
c语言·算法·leetcode