leetcode17-电话号码的字母组合

189 阅读1分钟

题目

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

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

示例 1:

输入: digits = "23"

输出: ["ad","ae","af","bd","be","bf","cd","ce","cf"]

来源:力扣(LeetCode)

链接:leetcode.cn/problems/le…

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

代码

public class Leetcode17 {
    public List<String> letterCombinations(String digits) {
        if (digits.length() == 0) {
            return new ArrayList<>();
        }
        Map<Integer, String[]> source = new HashMap<>();
        source.put(2, new String[]{"a", "b", "c"});
        source.put(3, new String[]{"d", "e", "f"});
        source.put(4, new String[]{"g", "h", "i"});
        source.put(5, new String[]{"j", "k", "l"});
        source.put(6, new String[]{"m", "n", "o"});
        source.put(7, new String[]{"p", "q", "r", "s"});
        source.put(8, new String[]{"t", "u", "v"});
        source.put(9, new String[]{"w", "x", "y", "z"});

        List<String> result = new ArrayList<>();
        addResult(0, "", source, digits, result);
        return result;
    }

    private void addResult(int i, String item, Map<Integer, String[]> source, String digits, List<String> result) {
        // 递归完最后一个元素
        if (i == digits.length()) {
            // 这道题没有 22 即重复数字这样的case,有的话要考虑去重
            result.add(item);
            return;
        }
        String[] sourceItem = source.get(digits.charAt(i) - '0');
        for (int j = 0; j < sourceItem.length; j++) {
            // 对当前索引的每一种可能 进行递归
            addResult(i + 1, item + sourceItem[j], source, digits, result);
        }
    }
}

解析

法一:递归回溯, 递归其实就是暴力的一种;对于已知循环层数的,直接用for循环去做;而对于题目中这种不知道循环层数的用递归去做即可,递归主要需要确定两点:

1.递归的元素,题目中就是数字串digits的索引下标,对于每一个下标会对应多种情况(例如数字2对应a b c)

2.退出递归的条件,题目就是数字串digits的索引下标越界时结束

法二:队列法,其实就是一次次遍历,然后把所有结果放到list中;到遍历下一次元素时,又把list中所有的结果拿出来与当前元素对应的可能性进行排列组合(例如元素2对应的abc);可参考 leetcode.cn/problems/le…

总结

这是一道比较基础的回溯题目,在该题目中其实是不存在回溯条件,在我上面提供的代码中,存在回溯,是因为多走了一次递归,其实在上一次递归,直接可以判断length是否相等;

但在注释中提到了,这道题没有 22 即重复数字这样的case,如果有的话要考虑去重,这样其实就会存在回溯条件,即提前终止递归;回溯题基本思路都是这样

引用leetcode官方解答的介绍:回溯算法用于寻找所有的可行解,如果发现一个解不可行,则会舍弃不可行的解。在这道题中,由于每个数字对应的每个字母都可能进入字母组合,因此不存在不可行的解,直接穷举所有的解即可。