leetcode hot 100-17. 电话号码的字母组合
17. 电话号码的字母组合
题目描述:
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
思路一:回溯
每一层递归消耗一个数字,这个数字映射的任何一个字符可以选择添加到 中间结果 sb 中, 所以是遍历该数字映射的每个字母,尝试把它加入到sb然后,递归取下个数字以及下个数字对应的字符,递归回来后需要回溯来消除影响
1 class Solution { 2 3 public List<String> letterCombinations(String digits) { 4 5 // 回溯,每一层消耗一个digits字符 6 String[] arr = {" ", " ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; 7 8 ArrayList<String> res = new ArrayList<>(); 9 if(digits == null || digits.length() == 0){ 10 return res; 11 } 12 traceBack(0, digits, new StringBuilder(), res, arr); 13 return res; 14 } 15 16 public void traceBack(int index, String digits, StringBuilder sb, ArrayList res, String[] arr){ 17 18 // 形成一个新的有效组合 19 if(index == digits.length()){ 20 res.add(sb.toString()); 21 return; 22 } 23 // 越界 24 if(index > digits.length()){ 25 return; 26 } 27 28 // 每一层消耗一个digit字符 29 int digit = digits.charAt(index) - '0'; 30 31 // 每个字符都可以选择附加到sb上 32 for(int i = 0; i < arr[digit].length(); i++){ 33 sb.append(arr[digit].charAt(i)); 34 // 递归取下一个字符 35 traceBack(index+1, digits, sb, res, arr); 36 sb.deleteCharAt(index); // 回溯 37 } 38 } 39 }
leetcode 执行用时:0 ms > 100.00%, 内存消耗:37.2 MB > 97.83%
复杂度分析:
时间复杂度:O(3n)~O(4n), n是digits数字的长度,之所以是一个范围,是因为有些数字映射的有4个字符
空间复杂度:取决于递归栈的深度,递归栈的深度又取决于digits字符串的长度,所以空间复杂度为O(n)
思路二:利用队列

浙公网安备 33010602011771号