数据结构与算法之数组: Leetcode 17. 电话号码的字母组合 (Typescript版)

电话号码的字母组合

  • https://leetcode.cn/problems/letter-combinations-of-a-phone-number/

描述

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

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

    1 2(abc) 3(def)
    4(ghi) 5(jkl) 6(mno)
    7(pqrs) 8(tuv) 9(wxyz)
    * 0 #

示例 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 )方案 1

function letterCombinations(digits: string): string[] {
  // 对输入做处理,如果小于1返回空
  if (digits.length < 1) return []
  // 建立电话号码键盘字典映射
  const dict: string[] = ['', '', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz']
  // 如果只给了一个按键,直接把按键内容取出来并按单个字符分组
  if (digits.length < 2) return dict[digits].split('')
  // 把输入字符串按单字符分隔变成数组,234 => [2,3,4]
  const num: string[] = digits.split('')
  // 保存键盘映射后的字母内容,如 23 => ['abc','def']
  const code: string[] = []
  num.forEach(item => {
    if (!dict[item]) {
      return
    }
    code.push(dict[item])
  })
  // 这里arr可以是数组和字符串的集合
  const comb = (arr: any[]) => {
    // 临时变量用来保存前两个组合的结果
    const tmp: string[] = []
    // 最外层的循环是遍历第一个元素,里层的循环是遍历第二个元素
    for (let i = 0, ilen = arr[0].length; i < ilen; i++) {
      for (let j = 0, jlen = arr[1].length; j < jlen; j++) {
        tmp.push(`${arr[0][i]}${arr[1][j]}`)
      }
    }
    // 从数组中索引为0开始删除,一共删除2个元素,将arr数组的前两项用 tmp 数组替代
    arr.splice(0, 2, tmp)
    if (arr.length > 1) {
      comb(arr)
    } else {
      return tmp
    }
    // 这是递归后形成的最后一个结果数组进行返回,这个数组只有一个元素
    return arr[0]
  }
  return comb(code)
};
  • 思路
    • 按照题目要求,可以任意输入符合要求的数值型字符串来获取最终的组合结果
    • 我们并不知道用户会输入多少字符,比如:2,3;2,3,4;2,3,4,5;2,3,4,5,6,…
    • 所以并不适合使用n层循环来暴力枚举,需要的是两两组合
    • 两两组合完事后,将前两个替换成最新的一个来与后面的一个再次进行两两组合
    • 直到最终只有一个数组的时候结束,这里用的递归的思路来处理的
    • 同时,我们字符串和数组都可以按下标来进行访问,这一点要注意
    • 这里一个重要的数组api是 splice,即这行:arr.splice(0, 2, tmp)
    • 这里arr是个any[]类型的数组,里面的数据结构是字符串和数组混合结构的数组
    • 这里考察的是组合关系
  • 这个dict字典的设计是比较合适的,前两个都是’', 为了和数字与下标的转换进行匹配
  • 但是重新审视这个算法,两个for循环嵌套,还是递归,这里时间复杂度较高,需要优化, 不是很理想

2 )方案 2

TODO

你可能感兴趣的:(Typescript,Data,Structure,and,Algorithms,leetcode,typescript,算法)