• 17. 电话号码的字母组合


    17. 电话号码的字母组合

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

    给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
    在这里插入图片描述

    示例 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’] 的一个数字。

    思路:(回溯

    Backtracking(回溯)属于 DFS。

    • 普通 DFS 主要用在 可达性问题 ,这种问题只需要执行到特定的位置然后返回即可。
    • 而 Backtracking 主要用于求解 排列组合 问题,例如有 { ‘a’,‘b’,‘c’ } 三个字符,求解所有由这三个字符排列得到的字符串,这种问题在执行到特定的位置返回之后还会继续执行求解过程。

    因为 Backtracking 不是立即返回,而要继续求解,因此在程序实现时,需要注意对元素的标记问题:

    • 在访问一个新元素进入新的递归调用时,需要将新元素标记为已经访问,这样才能在继续递归调用时不用重复访问该元素;
    • 但是在递归返回时,需要将元素标记为未访问,因为只需要保证在一个递归链中不同时访问一个元素,可以访问已经访问过但是不在当前递归链中的元素

    代码:(Java)

    import java.util.List;
    import java.util.ArrayList;
    
    public class letter_combination {
    
    	public static void main(String[] args) {
    		// TODO 自动生成的方法存根
    		String digits = "23";
    		System.out.println(letterCombinations(digits));
    
    	}
    	private static final String[] keys = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    	
    	public static List<String> letterCombinations(String digits) {
    		List<String> combinations = new ArrayList<>();
    		if(digits == null || digits.length() == 0) {
    			return combinations;
    		}
    		doCombination(new StringBuilder(), combinations,digits);
    		return combinations;
        }
    
    	private static void doCombination(StringBuilder prefix, List<String> combinations, String digits) {
    		// TODO 自动生成的方法存根
    		if(prefix.length() == digits.length()) {
    			combinations.add(prefix.toString());
    			return;
    		}
    		int curDigits = digits.charAt(prefix.length()) - '0';
    		String letters = keys[curDigits];
    		for(char c : letters.toCharArray()) {
    			prefix.append(c);
    			doCombination(prefix, combinations,digits);
    			prefix.deleteCharAt(prefix.length() - 1);
    		}
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    输出:

    在这里插入图片描述

    复杂度分析:

    时间复杂度: O ( 3 m × 4 n ) O(3^m×4^n) O(3m×4n),其中 m 是输入中对应 3 个字母的数字个数(包括数字 2、3、4、5、6、8),n 是输入中对应 4个字母的数字个数(包括数字 7、9),m+n 是输入数字的总个数。当输入包含 m 个对应 3 个字母的数字和 n个对应 4 个字母的数字时,不同的字母组合一共有 3 m × 4 n 3^m×4^n 3m×4n种,需要遍历每一种字母组合。

    空间复杂度:O(m+n),其中 m 是输入中对应 3 个字母的数字个数,n 是输入中对应 4 个字母的数字个数,m+n是输入数字的总个数。

    注:仅供学习参考!

    题目来源:力扣

  • 相关阅读:
    【Java算法】滑动窗口 上
    【08】基础知识:React中收集表单数据(非受控组件和受控组件)
    面试美团、头条、百度、京东,一名3年Java开发经验的面试总结,拿走不谢!
    在链表上实现 Partition 以及荷兰国旗问题
    Sha1,Sha256 哈希(摘要)处理
    (数据结构)数据结构的三要素
    MaterialDesign组件
    node开发时避免重复重启
    cpp中的函数模板
    【并发与多线程】Java多线程程序设计(一)
  • 原文地址:https://blog.csdn.net/weixin_43412762/article/details/128097224