LeetCode17.电话号码的字母组合

447 阅读1分钟

「这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

电话号码的数字组合

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

给出数字到字母的映射如下(与电话按键相同)。注意 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'] 的一个数字。

解法

首先在考虑到数字和字母映射问题的时候,我们应该考虑到使用map结构,将数字和对应字母字符串建立起映射,而对于这种暴力解法是很多层的for循环的问题,我们可以考虑回溯法,主要思路如下:

  1. 将数字和对应字母字符串存入map
  2. 递归函数里传入当前已经构建好的字符串,和当前构建的字符的index,用以判断递归是否完成
  3. 在构建字符串的过程中,先取出digits数组字符串中当前次序的数字对应的字符串,根据字符串的个数,依次创建不同的分支,拼接下一个字符串,重复这一操作,直到当前构建的字符的index大于digits.length - 1,也就是当前分支的字符串构建完毕,将构建的字符串压入结果数组,终止当前分支的递归操作

var letterCombinations = function(digits) {
        let res = [];
        // 如果传入的数字字符串长度为空,返回空的res
        if (digits.length === 0) return res;
        let map = new Map([
          ['2', 'abc'],
          ['3', 'def'],
          ['4', 'ghi'],
          ['5', 'jkl'],
          ['6', 'mno'],
          ['7', 'pqrs'],
          ['8', 'tuv'],
          ['9', 'wxyz']
        ])
        const dfs = function(str, i) {
            // 当前递归分支已经递归到了最后一层,即已经拼接了digits.length字符串
            if (i > digits.length - 1) { 
                // 将这个分支的解,推入结果数组
                res.push(str);
                // 结束当前递归分支          
                return;                    
            }
            // 获取当前数字对应的字母数组
            let letterStr = map.get(digits[i]);
            // 一个字母是一个选择,对应一个递归分支 
            for (let letter of letterStr) { 
                // 选择翻译成letter,生成新字符串,i指针右移继续翻译(递归)
                dfs(str + letter, i + 1);  
            }
        }
        dfs("", 0);
        return res;
};