leetcode热题100(17) - 电话号码的字母组合

Question

leetcode.cn/problems/le...

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

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例 1:

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

示例 2:

ini 复制代码
输入:digits = ""
输出:[]

示例 3:

arduino 复制代码
输入:digits = "2"
输出:["a","b","c"]

提示:

  • 0 <= digits.length <= 4
  • digits[i] 是范围 ['2', '9'] 的一个数字。

Solution

回溯法

遇到求组合的题目都可使用回溯法解答。

回溯法是什么?

简单来说就是可撤销的递归,解决回溯法的思路如下:

  1. 找到回溯出口,什么情况下我们找到了题目要求的一个解,此时不再继续递归
  2. 查找本趟调用中,有哪些可选项
  3. 遍历可选项,将每个项选择,然后递归调用处理下一个位置,然后撤销选择

对于本题,我们回答以上三个问题:

需要声明一个StringBuilder,来存储我们的选择字符

  1. 回溯出口,我们选择的字符串长度等于题目digits 的长度,此时查找到了一个解,将其插入最终的答案
  2. 每趟调用我们处理一位digit ,而每个digit 可选的字母是固定的,比如2 对应abc (图片已给出)
  3. 遍历abc ,在每趟遍历中选择当前的字母(StringBuilder.append),然后递归调用下一个digit ,然后再撤销选择(StringBuilder.deleteCharAt)
java 复制代码
class Solution1 {

        public List<String> letterCombinations(String digits) {
            if (digits.length() == 0) {
                return Collections.emptyList();
            }

            var answer = new ArrayList<String>();
            var sb = new StringBuilder();
            var charMap = new HashMap<Character, String>();
            charMap.put('2', "abc");
            charMap.put('3', "def");
            charMap.put('4', "ghi");
            charMap.put('5', "jkl");
            charMap.put('6', "mno");
            charMap.put('7', "pqrs");
            charMap.put('8', "tuv");
            charMap.put('9', "wxyz");
            helper(answer, sb, 0, digits, charMap);
            return answer;
        }

        private void helper(ArrayList<String> answer, StringBuilder sb, int index, String digits, HashMap<Character, String> charMap) {
            if (sb.length() == digits.length()) { // sb的长度已达到要求,因此写入最终答案
                answer.add(sb.toString());
                return;
            }
            var digit = digits.charAt(index); // 本轮的数字
            var chars = charMap.get(digit); // 该数字可以选择的字母列表
            for (int i = 0; i < chars.length(); i++) { // 遍历可选择的字母
                sb.append(chars.charAt(i)); // 选择该字母
                helper(answer, sb, index + 1, digits, charMap); // 递归处理下一个数字
                sb.deleteCharAt(index); // 当前不选该字母,这样可以撤回当前选择去尝试其他选择
            }
        }
    }

时间复杂度

O(3^m*4^n), m是长度为3字母的数字数量,n是长度为4字母的数字数量。对于每个字符,我们都有3种或4种选择。

空间复杂度

O(m+n) ,m长度为3个字母的数字数量,n长度为4个字母的数字数量,需要一个StringBuilder 来存储选择的数据,answers 所占空间不计入空间复杂度,charMap 大小是固定的。

相关推荐
我是哈哈hh1 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
Tisfy1 小时前
LeetCode 2187.完成旅途的最少时间:二分查找
算法·leetcode·二分查找·题解·二分
Mephisto.java1 小时前
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
sql·算法·leetcode
robin_suli1 小时前
滑动窗口->dd爱框框
算法
丶Darling.2 小时前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树
labuladuo5202 小时前
Codeforces Round 977 (Div. 2) C2 Adjust The Presentation (Hard Version)(思维,set)
数据结构·c++·算法
jiyisuifeng19912 小时前
代码随想录训练营第54天|单调栈+双指针
数据结构·算法
꧁༺❀氯ྀൢ躅ྀൢ❀༻꧂2 小时前
实验4 循环结构
c语言·算法·基础题
新晓·故知2 小时前
<基于递归实现线索二叉树的构造及遍历算法探讨>
数据结构·经验分享·笔记·算法·链表
总裁余(余登武)3 小时前
算法竞赛(Python)-万变中的不变“随机算法”
开发语言·python·算法