问题:

Given a digit string, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below.
Example:
Input:Digit string "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.

官方难度:

Medium

翻译:

给定一个数字组成的字符串,返回所有可能的字母集合。数字和字母的映射关系就像电话上显示的一样。

例子:

输入字符串:"23"

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

集合内的元素顺序没有规定。

方法一:

  1. 首先需要定义一个数值-字符的字典转译方法,使用长度为8的字符串数组,存放a-z的字母,然后根据输入的int值,返回一个char[]类型数组。
  2. 输入数字字符长度为0时,返回的是一个空的集合,而不是长度为1,包含一个空字符串的集合,需要特殊处理。
  3. 先将空字符串放入集合,然后开启递归。
  4. 递归终点是数字字符串长度为0,返回集合。
  5. 每次遍历集合的所有元素,根据数字字符串的第一个数字,排除所有可能性,将结果放回入参的集合,作为下一次递归的入参。
  6. 截取数字字符串的第一个数字的方法是:targetDigit.charAt(0)-‘a’。
  7. 注意入参检查

方法一的解题代码:

 public static List<String> letterCombinations(String digits) {
if (digits == null) {
throw new IllegalArgumentException("Input error");
}
String copyDigits = digits;
while (copyDigits.length() > 0) {
int i = copyDigits.charAt(0) - '0';
if (i < 2 || i > 9) {
throw new IllegalArgumentException("Input error");
}
copyDigits = copyDigits.substring(1);
}
// 只接受2-9的数值字符串
List<String> source = new LinkedList<>();
if (digits.equals("")) {
return source;
}
// 初始size需要等于1,不然之后不能循环
source.add("");
return format(source, digits);
} // 递归方法
private static List<String> format(List<String> source, String targetDigit) {
if (targetDigit.length() == 0) {
return source;
}
List<String> result = new LinkedList<>();
// 第一个数
int first = targetDigit.charAt(0) - '0';
char[] cArray = dict(first);
// source集合和targetDigit第一个数字对应字典的全排列
for (String str : source) {
for (char c : cArray) {
result.add(str + c);
}
}
// 将target转成source,继续递归
return format(result, targetDigit.substring(1));
} private static char[] dict(int num) {
String[] mappping = new String[] { "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
return mappping[num - 2].toCharArray();
}

letterCombinations

方法二:

1.  转译字典还能使用其他方法实现,不使用字符串数组,获得返回的char型数组的第一个值,然后依次添加。

2.  有一个隐藏的性质,得到的每一个字母字符串长度,与最初的数字字符串长度是一样的。然后指定声明集合为LinkedList,利用LinkedList.remove()方法删除并返回第一个元素,以及LinkedList.peek()方法得到集合的第一个元素。

3.  利用三次循环,外循环获取对应数字,除了方法一中的办法,还可以使用Character包装类自带的方法:Character.getNumbericValue()。

4.  中循环,使用while()循环判断集合的第一个元素的长度是否等于i,然后删除第一个元素,再用内循环转译数字凭借字符串,放入集合的尾部,这样可以保证遍历上一次集合的值。

方法二的解题代码:

     public static List<String> letterCombinations2(String digits) {
LinkedList<String> list = new LinkedList<String>();
if (digits.length() == 0) {
return list;
}
list.add("");
for (int i = 0; i < digits.length(); i++) {
int x = Character.getNumericValue(digits.charAt(i));
while (list.peek().length() == i) {
// 删除集合第一个元素并返回
String s = list.remove();
for (char c : dict2(x)) {
list.add(s + c);
}
}
}
return list;
} // 数字-字母转译字典
private static char[] dict2(int num) {
char[] result;
if (num == 9 || num == 7) {
result = new char[4];
} else {
result = new char[3];
}
// 注意7和9代表4个字母
char start;
if (num < 8) {
start = (char) ('a' + (num - 2) * 3);
} else {
start = (char) ('a' + (num - 2) * 3 + 1);
}
result[0] = start;
result[1] = (char) (start + 1);
result[2] = (char) (start + 2);
if (num == 9 || num == 7) {
result[3] = (char) (start + 3);
}
return result;
}

letterCombinations2

备注

  1. 就效率而言,两个方法是相同的,并没有高下之分。方法一的用法更加便于理解,但是其中使用了递归,所以在空间利用上要明显劣于方法二。推荐使用方法二。

相关链接:

https://leetcode.com/problems/letter-combinations-of-a-phone-number/

https://github.com/Gerrard-Feng/LeetCode/blob/master/LeetCode/src/com/gerrard/algorithm/medium/Q017.java

PS:如有不正确或提高效率的方法,欢迎留言,谢谢!

No.017:Letter Combinations of a Phone Number的更多相关文章

  1. LeetCode OJ:Letter Combinations of a Phone Number(数字字母组合)

    Given a digit string, return all possible letter combinations that the number could represent. A map ...

  2. LeetCode第[17]题(Java):Letter Combinations of a Phone Number

    题目:最长公共前缀 难度:EASY 题目内容: Given a string containing digits from 2-9 inclusive, return all possible let ...

  3. lintcode 中等题:Letter Combinations of a Phone Number 电话号码的字母组合

    题目 电话号码的字母组合 给一个数字字符串,每个数字代表一个字母,请返回其所有可能的字母组合. 下图的手机按键图,就表示了每个数字可以代表的字母. 样例 给定 "23" 返回 [& ...

  4. Letter Combinations of a Phone Number:深度优先和广度优先两种解法

    Letter Combinations of a Phone Number Given a digit string, return all possible letter combinations ...

  5. 《LeetBook》leetcode题解(17):Letter Combinations of a Phone Number[M]

    我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...

  6. [LintCode] Letter Combinations of a Phone Number 电话号码的字母组合

    Given a digit string, return all possible letter combinations that the number could represent. A map ...

  7. 69. Letter Combinations of a Phone Number

    Letter Combinations of a Phone Number Given a digit string, return all possible letter combinations ...

  8. 【leetcode】Letter Combinations of a Phone Number

    Letter Combinations of a Phone Number Given a digit string, return all possible letter combinations ...

  9. Letter Combinations of a Phone Number - LeetCode

    目录 题目链接 注意点 解法 小结 题目链接 Letter Combinations of a Phone Number - LeetCode 注意点 可以不用按字典序排序 解法 解法一:输入的数字逐 ...

随机推荐

  1. Atitit 图像处理 公共模块 矩阵扫描器

    Atitit 图像处理 公共模块 矩阵扫描器 1.1. 调用说明对矩阵像素遍历处理调用1 2. 矩阵扫描器主题结构1 2.1. 主要说明 从像素点开始填充矩阵1 2.2. 得到模板中心点所对应的图像坐 ...

  2. fir.im Weekly - iOS9 适配开发教程

    期待已久的 iOS 9 发布了,很多人更新完毕得出结论:这是值得升级的版本.随之而来的是适应 iOS9 开发技术.本期 Weekly 收集了一些关于 iOS9 相关的开发资源,希望对你有帮助. iOS ...

  3. 异步委托(APM)使用Func异步操作,处理耗时操作

    使用委托进行异步操作,处理一些耗时操作,防止主线程阻塞 使用例子: using System; using System.Collections.Generic; using System.Linq; ...

  4. ajax获取json对象

    ajax获取json对象 ajax获取json数据,都是一个原理,设置response 的Content-Type:application/json,这样浏览器自动会解析为json对象 $result ...

  5. CSS中如何实现未知尺寸图片垂直居中

    在曾经的 淘宝UED 招聘 中有这样一道题目: “使用纯CSS实现未知尺寸的图片(但高宽都小于200px)在200px的正方形容器中水平和垂直居中.” 当然出题并不是随意,而是有其现实的原因,垂直居中 ...

  6. HTML5标签嵌套规则

    × 目录 [1]分类 [2]子元素 [3]总结 前面的话 在html5中,<a>元素的子元素可以是块级元素,这在以前是被认为不符合规则的.本文将详细介绍html5的标签嵌套规则 分类 ht ...

  7. 文本溢出text-overflow和文本阴影text-shadow

    前面的话 CSS3新增了一些关于文本的样式,其中text-overflow文本溢出和text-shadow文本阴影有些特别.因为它们有对应的overflow溢出属性和box-shadow盒子阴影属性. ...

  8. Python函数参数默认值的陷阱和原理深究"

    本文将介绍使用mutable对象作为Python函数参数默认值潜在的危害,以及其实现原理和设计目的 本博客已经迁移至: http://cenalulu.github.io/ 本篇博文已经迁移,阅读全文 ...

  9. linux安装nginx

    nginx启动.重启.关闭 安装: http://www.cnblogs.com/skynet/p/4146083.html 一.启动 cd usr/local/nginx/sbin ./nginx ...

  10. Android基于mAppWidget实现手绘地图(六)–如何展示地图对象

    为了展示选中的点,你需要完成以下步骤: 1.创建或者获得一个已经存在的图层 2.创建代表选中点的地图对象 3.把地图对象添加到图层 创建新图层 使用以下代码片段创建图层 int COFFEE_SHOP ...