[LeetCode] 17. 电话号码的字母组合

时间:2019-09-22
本文章向大家介绍[LeetCode] 17. 电话号码的字母组合,主要包括[LeetCode] 17. 电话号码的字母组合使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

传送门:[LeetCode] 17. 电话号码的字母组合

题目描述

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

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

说明:

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

示例 :

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

分析

  • 一、迭代

    1. 判断字符串是否为空,为空直接返回,否则加入一个空字符串

      List<String> res = new ArrayList<>();
      if (digits.isEmpty()) {
          return res;
      }
      res.add("");
    2. 建表,保存每个数字代表的字符串

      String[] table = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs",
                        "tuv", "wxyz" };
    3. 遍历数字字符串 digits 时创建一个临时的字符串数组 temp ,通过数字取出字符串,然后遍历取出的字符串中的所有字符,再遍历当前 res 中的每一个字符串,将字符加到字符串后面,并加入到临时字符串数组 temp 中,两重遍历完成后,更新 res 为 temp ;(看不懂文字直接看代码,代码容易看懂)

      for (char num : digits.toCharArray()) {
          List<String> temp = new ArrayList<>();
          for (char tail : table[num - '0'].toCharArray()) {
              for (String pre : res) {
                  temp.add(pre + tail);
              }
          }
          res = temp;
      }
  • 二、回溯

    1. 判空、建表与上述一致

    2. 递归函数写法,使用 s 记录当前的字符串,level 记录当前的字符串字符个数;

      每次递归先判断 level ,当 level 等于 digits 长度时,将字符串s加入结果数组 res ;

      否则通过 digits 中的数字取出字符串,然后遍历这个取出的字符串,将每个字符都加到当前的组合后面,并调用递归函数。

      public void backtracking(String digits, String s, int level) {
          if (level == digits.length()) {
              res.add(s);
              return;
          }
          for (char tail : table[digits.charAt(level) - '0'].toCharArray()) {
              backtracking(digits, s + tail, level + 1);
          }
      }
    3. 调用递归函数时,传入 s 为空字符串"",level 为0;

      public List<String> letterCombinations(String digits) {
          if (digits.isEmpty()) {
              return res;
          }
          backtracking(digits, "", 0);
          return res;
      }
  • 三、队列

    1. 判空、建表与上述一致

    2. 思想类似第一种迭代,但利用了队列的先进先出,不用每次创建临时的数组

      for (int i = 0; i < digits.length(); i++) {
          // 把数字字符转为数字
          int num = Character.getNumericValue(digits.charAt(i));
          // 利用了当前保存的结果字符串长度与当前遍历的数字下标相等的条件进行判断
          while (res.peek().length() == i) {
              String s = res.poll();
              for (char tail : table[num].toCharArray()) {
                  res.offer(s + tail);
              }
          }
      }

代码

  • 解法一:迭代

    class Solution {
        public List<String> letterCombinations(String digits) {
            List<String> res = new ArrayList<>();
            if (digits.isEmpty()) {
                return res;
            }
            res.add("");
            String[] table = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs",
                              "tuv", "wxyz" };
            for (char num : digits.toCharArray()) {
                List<String> temp = new ArrayList<>();
                for (char tail : table[num - '0'].toCharArray()) {
                    for (String pre : res) {
                        temp.add(pre + tail);
                    }
                }
                res = temp;
            }
            return res;
        }
    }
  • 解法二:回溯

    class Solution {
        List<String> res = new ArrayList<>();
        String[] table = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv",
                          "wxyz" };
    
        public List<String> letterCombinations(String digits) {
            if (digits.isEmpty()) {
                return res;
            }
            backtracking(digits, "", 0);
            return res;
        }
    
        public void backtracking(String digits, String s, int level) {
            if (level == digits.length()) {
                res.add(s);
                return;
            }
            for (char tail : table[digits.charAt(level) - '0'].toCharArray()) {
                backtracking(digits, s + tail, level + 1);
            }
        }
    }
  • 解法三:队列

    public List<String> letterCombinations(String digits) {
        LinkedList<String> res = new LinkedList<>();
        String[] table = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs",
                          "tuv", "wxyz" };
        if (digits.isEmpty()) {
            return res;
        }
        res.add("");
        for (int i = 0; i < digits.length(); i++) {
            // 把数字字符转为数字
            int num = Character.getNumericValue(digits.charAt(i));
            // 利用了当前保存的结果字符串长度与当前遍历的数字下标相等的条件进行判断
            while (res.peek().length() == i) {
                String s = res.poll();
                for (char tail : table[num].toCharArray()) {
                    res.offer(s + tail);
                }
            }
        }
        return res;
    }

小结

Character.getNumericValue(char ch)

该方法获取参数ch的数值,有三种返回值

  1. 若ch字符的数值为非负整数,返回ch字符对应的数值
  2. 若为不是非负整数,返回-2
  3. 若字符没有数值,返回-1

原文地址:https://www.cnblogs.com/qiu_jiaqi/p/LeetCode_17.html