算法题目整理分析--电话号码组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

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

示例:

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

说明:尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

初步解答

export default (str) => {
    // 创建映射
    let map = ['', 1, 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz']
    // 创建将数字分割成数组
    let strArr = str.split('')
    // 创建字母数组 12 =》 ['abc','def']
    let code = []
    strArr.forEach(item => {
        if (map[item]) {
            code.push(map[item])
        }
    })
    let mergeArr = (arr) => {
        let temp = []
        if (arr.length > 1) {
            for (let i = 0, il = arr[0].length; i < il; i++) {
                for (let j = 0, jl = arr[1].length; j < jl; j++) {
                    temp.push(`${arr[0][i]}${arr[1][j]}`)
                }
            }
            arr.splice(0, 2, temp)
            return mergeArr(arr)
        } else {
            return arr[0]
        }
    }
    return mergeArr(code)
}

思路整理:

  • 1:创建与数字对应的映射,将字符串专程对应数组
  • 2:对数组中前两个进行遍历合并
  • 3:合并结果保存在缓存数组中
  • 4:将原数组中的两位替换成缓存数组
  • 5:通过递归,继续处理

思路肯定是没有问题的,处理结果也基本达到了预期。但是却忽略了几个问题:

  • 1:传入为空的时候报错
  • 2:传入一个字符的时候报错

第二次测试

export default (digits) => {
  if (!digits) {
    return []
  }
  // 创建映射
  let map = ['', 1, 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz']
  // 创建将数字分割成数组
  let strArr = digits.split('')
  // 创建字母数组 12 =》 ['abc','def']
  let code = []
  strArr.forEach(item => {
    if (map[item]) {
      code.push(map[item])
    }
  })
  let mergeArr = (arr) => {
    let temp = []
    if (arr.length > 1) {
      for (let i = 0, il = arr[0].length; i < il; i++) {
        for (let j = 0, jl = arr[1].length; j < jl; j++) {
          temp.push(`${arr[0][i]}${arr[1][j]}`)
        }
      }
      arr.splice(0, 2, temp)
      return mergeArr(arr)
    } else {
      return arr[0] instanceof Array ? arr[0] : arr[0].split('')
    }
  }
  return mergeArr(code)
}

添加了两个异常处理:

  • 1:传入空时,直接返回
  • 2:返回时判断,如果是数组就返回,如果不是则将字符串分割成数组返回

随机浏览