递归与回溯12:电话号码问题

Posted 纵横千里,捭阖四方

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了递归与回溯12:电话号码问题相关的知识,希望对你有一定的参考价值。

LeetCode17,电话号码组合问题,也是热度非常高的一个题目,给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:

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

我们说回溯仍然会存在暴力枚举的情况,这个题就很典型,例如如果输入23,那么,2就有 a、b、c三种情况,3有d、e、f三种情况。所以组合一下就一共就有3*3=9种。如果是233,那么就是27种。从实现的角度来说,两个数字就是两层循环,三个数字就是3层循环。这样是很好理解的,但是如果随便输入一个数字,你该怎么写有几层循环呢?很显然就不能再暴力搜索了,这个与组合问题几乎一样。

进入正题之前,先看一个小问题,这里的9对应4个字母,而1则没有。那该怎么建立字母和数字之间的映射呢?简单,用一个数组就行了,不要写一堆的if else判断。

 String[] numString = "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz";

接下来我们就用回溯来解决n层循环的问题,输入23对应的树就是这样的:

 树的深度就是输入的数字个数,这里是23,树的深度就是2。而所有的叶子节点就是我们需要的结果["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]。所以这里的终止条件就是,如果当前执行的index 等于输入的数字个数(digits.size)了。注意这里的index是从2开始的,与前面的startIndex不同。

而这里的index也恰好就是上面数组的索引,所以取index指向的数字,并找到对应的字符集,使用for循环来枚举出来,然后循环体内就是回溯过程了。基本实现过程如下:

class Solution 

    List<String> list = new ArrayList<>();

    public List<String> letterCombinations(String digits) 
        if (digits == null || digits.length() == 0) 
            return list;
        
        //初始对应所有的数字,为了直接对应2-9,新增了两个无效的字符串""
        String[] numString = "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz";
     
        backTracking(digits, numString, 0);
        return list;

    

    //每次迭代获取一个字符串,所以会设计大量的字符串拼接,所以这里选择更为高效的 StringBuild
    StringBuilder temp = new StringBuilder();

    //比如digits如果为"23",num 为0,则str表示2对应的 abc
    public void backTracking(String digits, String[] numString, int num) 
        //遍历全部一次记录一次得到的字符串
        if (num == digits.length()) 
            list.add(temp.toString());
            return;
        
        //str 表示当前num对应的字符串
        String str = numString[digits.charAt(num) - '0'];
        for (int i = 0; i < str.length(); i++) 
            temp.append(str.charAt(i));
            //c
            backTracking(digits, numString, num + 1);
            //剔除末尾的继续尝试
            temp.deleteCharAt(temp.length() - 1);
        
    

以上是关于递归与回溯12:电话号码问题的主要内容,如果未能解决你的问题,请参考以下文章

17. 电话号码的字母组合(递归+回溯)

leetcode 17. 电话号码的字母组合----回溯算法

电话号码的字母组合

递归与回溯:python列表组合问题

回溯算法例题----电话号码的字母组合

LeetCode----电话号码的字母组合「回溯」