算法——17. 【中等】电话号码字母组合

130 阅读1分钟

题目

image.png

示例 1:

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

示例 2:

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

示例 3:

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

提示:

0 <= digits.length <= 4
digits[i] 是范围 ['2', '9'] 的一个数字。

解法

1尝试:暴力解法

代码

function letterCombinations(digits: string): string[] {
// 静态索引值
const numMap = {
  2: ['a', 'b', 'c'],
  3: ['d', 'e', 'f'],
  4: ['g', 'h', 'i'],
  5: ['j', 'k', 'l'],
  6: ['m', 'n', 'o'],
  7: ['p', 'q', 'r','s'],
  8: ['t', 'u', 'v'],
  9: ['w', 'x', 'y', 'z']
}

let returnValue = [] // 存储返回值
 
// 提前返回
if(digits.length === 0) {
  return returnValue
}
 // 提前返回
if(digits.length === 1) {
  return numMap[digits]
}

// 字符串转数组,方便遍历
const digitsArr = digits.split('')

// 遍历输入的号码
digitsArr.forEach(num => {
  if(returnValue.length === 0) { // 第一次暂存数字对应的字母数组
    returnValue = [...numMap[num]]
  } else {
    let stash = []  // 暂存区
    returnValue.forEach(str => { // 取出历史数据 和 对应数字的字母拼接
      numMap[num].forEach(add => { // 遍历数字对应字母
        stash.push(str+add)
      });
    })
    returnValue = [...stash]  // 重新赋值
  }
})

return returnValue
};

最后看看AC结果:

25/25 cases passed (72 ms)
Your runtime beats 33.24 % of typescript submissions
Your memory usage beats 28.77 % of typescript submissions (42.4 MB)

2更好答案:递归

代码

function letterCombinations(digits: string): string[] {
  const numMap = {
    2: ['a', 'b', 'c'],
    3: ['d', 'e', 'f'],
    4: ['g', 'h', 'i'],
    5: ['j', 'k', 'l'],
    6: ['m', 'n', 'o'],
    7: ['p', 'q', 'r','s'],
    8: ['t', 'u', 'v'],
    9: ['w', 'x', 'y', 'z']
  }

  let returnValue = []

  if(digits.length === 0) {
    return returnValue
  }
  if(digits.length === 1) {
    return numMap[digits]
  }
  
 /**
 * @param preStr 当前字符串
 * @param digitsStr 未处理的数字
 */
  const deepAdd = (preStr:string, digitsStr: string) => {
    if(digitsStr === '') { // 终止递归 暂存数据
      returnValue.push(preStr)
    } else {
      const num = digitsStr[0]  // 取第一位数字

      numMap[num].forEach(element => { // 遍历字母
        deepAdd(preStr + element, digitsStr.slice(1)) // 递归
      });
    }
  }
  

  deepAdd('', digits)

  return returnValue

};

最后看看AC结果

25/25 cases passed (52 ms)
Your runtime beats 97.77 % of typescript submissions
Your memory usage beats 14.81 % of typescript submissions (42.5 MB)

总结

  1. 存历史数据除了用声明的方式显示存储,还可以使用传参方式把历史数据记录下来,将数据存储起来!!!
  2. 字符串操作:
  • 字符串变数组: string.split('')
  • 字符串截取: a.slice(startIndex[, endIndex]) // 不改变a的值, startIndex, endIndex均可以取负数。