LeetCode刷题笔记(Java实现)-- 17.电话号码的字母组合

题目难度:
Medium

题目要求:
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
在这里插入图片描述
示例:
输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]

编码思路:(建议对照代码理解)
1.创建最后输出的字符组合的集合combinations;
注:ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
2.如果输入的数字串长度为0,就直接返回,说明为空;
3.创建哈希表,存放数字与字母的对应关系;
4.定义回溯函数,确定传递的参数有【字符组合的集合(combinations),参考的哈希表(phoneMap),给定的数字串(digits),当前数字的位置(index),当前组成的字母组合(combination)】;
5.构造回溯函数:{
(1)如果digits.length()==index,最后一个数字都回溯完了,说明已经是最长的组合,可以将当前的一个字母组合加入combinations合集中,等待返回;
(2)其他情况,以当前数字对应的字母串长度为边界条件,在这个长度内,对所有的字母进行循环,并将其加入当前字母组合的末尾,再回溯进入下一个数字对应的字母串;
}

代码:

/*
 * @lc app=leetcode.cn id=17 lang=java
 *
 * [17] 电话号码的字母组合
 */

// @lc code=start
class Solution {
    public List<String> letterCombinations(String digits) {

        //创建最后输出的字符组合的集合combinations;
        List<String> combinations = new ArrayList<String>();

        //如果输入的数字串长度为0,就返回
        if(digits.length()==0){
            return combinations;
        }

        //创建哈希表,存放数字与字母的对应关系
        Map<Character,String> phoneMap= new HashMap<Character,String>(){{
            put('2', "abc");
            put('3', "def");
            put('4', "ghi");
            put('5', "jkl");
            put('6', "mno");
            put('7', "pqrs");
            put('8', "tuv");
            put('9', "wxyz");
        }};

        //定义回溯函数
        backtrack(combinations,phoneMap,digits,0,new StringBuffer());
        
        return combinations;
    }

    //构造回溯函数
    public void backtrack(List<String> combinations,Map<Character,String> phoneMap,String digits,int index,StringBuffer combination){
        //如果最后一个数字都回溯完了,说明已经是最长的组合,可以加入combinations中,等待返回
        if(digits.length()==index){
            combinations.add(combination.toString());
        }
        //
        else{
            //提取数字串的index位置的数字
            char digit=digits.charAt(index);
            //利用这个数字从哈希表中,找出对应的字母串
            String letters = phoneMap.get(digit);
            //以这个字母串的长度为条件进行循环
            int lettersCount=letters.length();
            //循环
            for (int i = 0; i < lettersCount; i++) {
                //将这个数字下i位置的字母加入字符串
                combination.append(letters.charAt(i));
                //回溯下一个数字对应的字母串
                backtrack(combinations, phoneMap, digits, index + 1, combination);
                //此时,最长的,符合要求的字符串已经加到combinatiions中了,将最后一个数字
                combination.deleteCharAt(index);
            }
        }
    }  
}

时间复杂度:O(3 ^m × 4 ^n )。m为指定数字字符串中,对应3个字母的个数,n为指定数字字符串中,对应4个字母的个数(包括数字 7、9)。不同的字母组合一共有 3 ^m × 4 ^n 种,需要遍历每一种字母组合。
空间复杂度:O(m+n)。回溯调用m+n次。

补充:****【回溯和递归的区别】:
递归是一种算法,自己调用自己;
回溯是一种算法思想,可以用递归实现,回溯一定有出口(尽头);
可以参考8皇后问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值