夯实算法-电话号码的字母组合

202 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的26天,点击查看活动详情

题目:LeetCode

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

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

200px-telephone-keypad2svg.png

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

解题思路

用回溯算法可以解决此问题。

需要注意整体的组合仍是按顺序的,是由数字定义的顺序。

要这么理解,解决这个问题需要 nnn 步,n=len(digits)n = len(digits)n=len(digits),也即是输入字串的长度。每一步有3到4个选择,也即是每个数字对应的字符集合。

对于每个字符选择,向后递归,当到了 nnn 步后,就得到了一个组合,添加以结果列表中即可。选择了一个字符后,要回溯,以选择下一个字符,这里直接用字符串拼接,所以不用额外的回溯动作。

唯一要小心的就是7和9对应4个字符,其余都是3个。

代码实现

private List < String > result;

public List < String > letterCombinations(String digits) {
    result = new ArrayList < > ();

    if (digits == null || digits.length() == 0) {
        return result;
    }

    combine(digits, 0, "");

    return result;
}

private void combine(String digits, int index, String set) {
    if (index == digits.length()) {
        result.add(set);
    } else if (index < digits.length()) {
        char[] keys = map(digits.charAt(index));
        for (char ch: keys) {
            combine(digits, index + 1, set + ch);
        }
    }
}

private char[] map(char ch) {
    switch (ch) {
        case '2':
            return new char[] {
                'a', 'b', 'c'
            };
        case '3':
            return new char[] {
                'd', 'e', 'f'
            };
        case '4':
            return new char[] {
                'g', 'h', 'i'
            };
        case '5':
            return new char[] {
                'j', 'k', 'l'
            };
        case '6':
            return new char[] {
                'm', 'n', 'o'
            };
        case '7':
            return new char[] {
                'p', 'q', 'r', 's'
            };
        case '8':
            return new char[] {
                't', 'u', 'v'
            };
        case '9':
            return new char[] {
                'w', 'x', 'y', 'z'
            };
    }

    // should not be here
    return new char[] {};
}

运行结果

Snipaste_2022-12-23_23-06-07.png

复杂度分析

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)  一起分享知识, Keep Learning!