zoukankan      html  css  js  c++  java
  • Backtracking_17. *的字母组合

    给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

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

     

    示例:

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

    说明:
    尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number


    思路:

    Backtracking(回溯)属于 DFS。有很多经典的问题,如八皇后。

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

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

    • 在访问一个新元素进入新的递归调用时,需要将新元素标记为已经访问,这样才能在继续递归调用时不用重复访问该元素;
    • 但是在递归返回时,需要将元素标记为未访问,因为只需要保证在一个递归链中不同时访问一个元素,可以访问已经访问过但是不在当前递归链中的元素。
    class Solution {
        private static final String[] KEYS = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    
        public 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 void doCombination(StringBuilder prefix, List<String> combinations, final String digits) {
            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); // 删除
            }
        }
    }

    这段是官网的

    class Solution {
        Map<String, String> phone = new HashMap<>() {{
            put("2", "abc");
            put("3", "def");
            put("4", "ghi");
            put("5", "jkl");
            put("6", "mno");
            put("7", "pqrs");
            put("8", "tuv");
            put("9", "wxyz");
        }};
    
        List<String> output = new ArrayList<>();
    
        public List<String> letterCombinations(String digits) {
            if (digits.length() != 0)
                backtrack("", digits);
            return output;
        }
    
        public void backtrack(String combination, String next_digits) {
            if (next_digits.length() == 0) {
                //如果传进来的是空的,返回就是空的
                output.add(combination);
            }
            else {
                //获取传进来的KEY,先获取digits的第一个内容,分割出来
                String digit = next_digits.substring(0, 1);
                //获取对应的value
                String letters = phone.get(digit);
                for (int i = 0; i < letters.length(); i++) {
                    //有value中有几个字母就循环几次,每次取出一个字母拼接起来
                    String letter = phone.get(digit).substring(i, i + 1);
                    backtrack(combination + letter, next_digits.substring(1));
                }
            }
        }
    }
  • 相关阅读:
    Symbol
    前端微信支付步骤
    获取url参数值(可解码中文值)
    HTML5--canvas与svg的使用
    js-图片img转base64格式
    echarts 地图
    echarts 水球图
    react长列表性能优化
    CSS Modules
    react路由
  • 原文地址:https://www.cnblogs.com/zzxisgod/p/13366576.html
Copyright © 2011-2022 走看看