返回

LeetCode题解:17. 电话号码的字母组合 - 队列,JavaScript,附带详细注释

前端

1. 问题

给定一个仅包含数字 2-9 的字符串,返回该字符串对应的所有电话号码字母组合。数字与字母的映射如下:

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

例如:

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

2. 算法分析

本题可以使用回溯算法和队列数据结构来解决。回溯算法可以穷举所有可能的字母组合,而队列可以存储已经生成的组合,并将其作为下一次迭代的起点。具体算法流程如下:

  1. 对于输入的数字字符串,将每个数字对应的字母映射存储在队列中。
  2. 从队列中逐个取出字母,并将其与队列中其他字母组合。
  3. 将组合好的字母重新入队。
  4. 重复步骤2和步骤3,直到队列为空。
  5. 此时,队列中存储的所有字母组合就是问题的解。

3. JavaScript代码实现

/**
 * 给定一个仅包含数字 2-9 的字符串,返回该字符串对应的所有电话号码字母组合。
 *
 * @param {string} digits 数字字符串
 * @return {string[]} 字母组合列表
 */
const letterCombinations = (digits) => {
  if (digits === null || digits.length === 0) {
    return [];
  }

  // 数字与字母的映射表
  const mapping = {
    '2': 'abc',
    '3': 'def',
    '4': 'ghi',
    '5': 'jkl',
    '6': 'mno',
    '7': 'pqrs',
    '8': 'tuv',
    '9': 'wxyz',
  };

  // 创建一个队列,存储已经生成的组合
  const queue = [];

  // 将第一个数字对应的字母映射入队
  for (let i = 0; i < mapping[digits[0]].length; i++) {
    queue.push(mapping[digits[0]][i]);
  }

  // 逐个取出队列中的字母,并将其与队列中其他字母组合
  while (queue.length > 0) {
    const currentLetter = queue.shift();

    // 如果队列为空,则说明所有可能的组合都已经生成,直接返回
    if (queue.length === 0) {
      return result;
    }

    // 将当前字母与队列中其他字母组合
    for (let i = 0; i < mapping[digits[1]].length; i++) {
      queue.push(currentLetter + mapping[digits[1]][i]);
    }
  }
};

4. 动画解析

为了帮助读者更好地理解算法原理,我们提供了动画解析。动画中,队列以矩形框表示,每个矩形框中存储着一个字母。算法从队列中逐个取出字母,并将其与队列中其他字母组合。组合好的字母重新入队,直到队列为空。最终,队列中存储的所有字母组合就是问题的解。

5. 总结

本题考察了回溯算法和队列数据结构的应用。通过本题,读者可以深入了解这两种算法在实际问题中的应用,并掌握LeetCode题解的解题思路。