乘风破浪:LeetCode真题_017_Letter Combinations of a Phone Number

一、前言

如何让两个或者多个集合中的随机挑选的元素结合到一起,并且得到所有的可能呢?我们可能事先并不知道会用到哪几个集合,因此我们可以通过递归方法来解决。

二、Letter Combinations of a Phone Number

2.1 问题

2.2 分析和解决

通过上面的题目,我们基本上可以理解题意了,但是我们要怎么去处理呢,这个时候就需要用到递归算法了。

public class Solution {
private static final String[] KEYS = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; public List<String> letterCombinations(String digits) {
List<String> ret = new LinkedList<String>();
combination("", digits, 0, ret);
if(ret.get(0) == ""){
ret.clear();
}
return ret;
} private void combination(String prefix, String digits, int offset, List<String> ret) {
if (offset >= digits.length()) {
ret.add(prefix);
return;
}
String letters = KEYS[(digits.charAt(offset) - '0')];
for (int i = 0; i < letters.length(); i++) {
combination(prefix + letters.charAt(i), digits, offset + 1, ret);
}
}

}

     这里特别要注意,如果输入为空的情况下,我们的输出也必须为空,比如[]作为输入,[]也必须作为输出,而不是[""]。

     当然我们也可以看看不同的递归写法:

import java.util.LinkedList;
import java.util.List; public class Solution { private String[] map = {
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz",
};
private List<String> result; // 存储最终结果
private char[] chars; // 保存去掉0,1字符的结果
private char[] curResult; // 存储中间结果
private int end = 0; // 字符数组中的第一个未使用的位置
private int handle = 0; // 当前处理的是第几个字符数字 /**
* 题目大意
* 给定一个数字串,返回数字上所有字符的所有组合,数字到字符的映射如上图所示。
* 注意: 尽管上面的结果以字符顺序排列的,你可以以任何顺序返回结果。
*
* 解题思路
* 一个数组保存数字和字的映射关用系,根据数字串的输入,找到对应的字符,组合结果。
*/
public List<String> letterCombinations(String digits) {
result = new LinkedList<>(); if (digits != null && digits.length() > 0) { chars = digits.toCharArray(); // 对字符串进行处理,去掉0和1
// 找第一个0或者1的位置
while (end < digits.length() && chars[end] != '0' && chars[end] != '1') {
end++;
} handle = end + 1;
while (handle < chars.length) {
if (chars[handle] != '0' && chars[handle] != '1') {
chars[end] = chars[handle];
end++;
}
handle++;
} curResult = new char[end];
// while结束后,end为有效字符的长度
handle = 0; // 指向第一个有效字符的位置 letterCombinations();
}
return result;
} private void letterCombinations() {
if (handle >= end) {
result.add(new String(curResult));
} else {
int num = chars[handle] - '2';
for (int i = 0; i < map[num].length(); i++) {
curResult[handle] = map[num].charAt(i);
handle++;
letterCombinations();
handle--;
}
}
}
}

     上面的递归也是非常有意思的,大家可以仔细的玩味一下。

   接下来我们再看一种自己构建队列的方式来处理的方法:

import java.util.*;
class Solution {
public List<String> letterCombinations(String digits) {
LinkedList<String> result = new LinkedList<>();
if(digits.isEmpty())
return result;
String[] mapping = new String[] {"0", "1", "abc","def","ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
result.add(""); while(result.peek().length() != digits.length()) {
String remove = result.remove();
String map = mapping[digits.charAt(remove.length())-'0']; for(char c : map.toCharArray()) {
result.addLast(remove + c);
} } return result;
}
}

   在这里定义了一个result队列,首先看看当前的指针所对应的元素的长度有没有达到给定的字符串的长度:

result.peek().length()

     如果没有则继续,如果已经达到了,那么已经完成了遍历。

     其次,最开始的元素出队列,它的长度就是下一个需要选择的给定字符串的位置,因此取出对应的数字,找到对应的字符串,然后将弹出的字符串和这些字符串拼接,入队列。

     String map = mapping[digits.charAt(remove.length())-'0'];
     for(char c : map.toCharArray()) {
result.addLast(remove + c);
}

       依次这样遍历,知道满足条件,这样就得到了结果。

       我们举一个例子:

     同样的其实可以转换成堆栈来做,道理是一样的。

三、总结

当我们遇到问题的时候,不能解决的情况下一定要想到递归,动态规划这些方法,不然的话我们将无从做起,另外递归也有许多的技巧,都是可以转换成堆栈或者队列来解决的。

乘风破浪:LeetCode真题_017_Letter Combinations of a Phone Number的更多相关文章

  1. 乘风破浪:LeetCode真题_022_Generate Parentheses

    乘风破浪:LeetCode真题_022_Generate Parentheses 一.前言 关于括号的题目,我们已经遇到过了验证正确性的题目,现在让我们生成合法的括号列表,怎么办呢?想来想去还是递归比 ...

  2. 乘风破浪:LeetCode真题_041_First Missing Positive

    乘风破浪:LeetCode真题_041_First Missing Positive 一.前言 这次的题目之所以说是难,其实还是在于对于某些空间和时间的限制. 二.First Missing Posi ...

  3. 乘风破浪:LeetCode真题_040_Combination Sum II

    乘风破浪:LeetCode真题_040_Combination Sum II 一.前言 这次和上次的区别是元素不能重复使用了,这也简单,每一次去掉使用过的元素即可. 二.Combination Sum ...

  4. 乘风破浪:LeetCode真题_039_Combination Sum

    乘风破浪:LeetCode真题_039_Combination Sum 一.前言     这一道题又是集合上面的问题,可以重复使用数字,来求得几个数之和等于目标. 二.Combination Sum ...

  5. 乘风破浪:LeetCode真题_038_Count and Say

    乘风破浪:LeetCode真题_038_Count and Say 一.前言     这一道题目,很类似于小学的问题,但是如果硬是要将输入和结果产生数值上的联系就会产生混乱了,因此我们要打破思维定势. ...

  6. 乘风破浪:LeetCode真题_037_Sudoku Solver

    乘风破浪:LeetCode真题_037_Sudoku Solver 一.前言 这次我们对于上次的模型做一个扩展并求解. 二.Sudoku Solver 2.1 问题 2.2 分析与解决     这道题 ...

  7. 乘风破浪:LeetCode真题_036_Valid Sudoku

    乘风破浪:LeetCode真题_036_Valid Sudoku 一.前言 有的时候对于一些基础知识的掌握,对我们是至关重要的,比如ASCII重要字符的表示,比如一些基本类型的长度. 二.Valid ...

  8. 乘风破浪:LeetCode真题_035_Search Insert Position

    乘风破浪:LeetCode真题_035_Search Insert Position 一.前言 这次的问题比较简单,也没有限制时间复杂度,但是要注意一些细节上的问题. 二.Search Insert ...

  9. 乘风破浪:LeetCode真题_034_Find First and Last Position of Element in Sorted Array

    乘风破浪:LeetCode真题_034_Find First and Last Position of Element in Sorted Array 一.前言 这次我们还是要改造二分搜索,但是想法却 ...

随机推荐

  1. JavaScript数据结构-12.散列碰撞(线性探测法)

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 记一次接口调用耗时服务端PHP-FPM配置调优

    最近测试人员不时有反馈,APP首页打开会出现除了基本的页面布局,需要展示数据的地方都是空白. 想着最近首页接口有过调整,新增数据.会不会是接口改动导致的?? 但APP首页接口都是读取redis的,应该 ...

  3. Response.cookies和Request.cookies

    Response.cookies和Request.cookies的区别很重要,由于方法基本都是差不多的,特别对于初学者而言,很容易出现混淆. 简单说就是创建cookie用response,获取cook ...

  4. Orchard源码:热启动

    概述 IIS线程池中的线程数量是有限制的.当有多个长时间请求时,可能会耗尽IIS可用线程.出现503错误.在MVC中.当遇到非CPU操作的长时间请求时,MVC提供了异步方法来解决这个问题. 例:利用a ...

  5. 简单封装axios api

    可以在代码逻辑中写axios请求,处理请求结果,但是随着项目越来越大,代码会很繁琐,不容易维护,所以,可以把一些在所有请求中都要处理的逻辑抽取出来,封装成api方法.比如每次请求中都要判断是否有权限, ...

  6. Cheatsheet: 2017 06.01 ~ 06.30

    .NET Porting a .NET Framework library to .NET Core Performance Improvements in .NET Core High-perfor ...

  7. 一:Bootstrap-css样式

    页面大块布局: div.container 栅格系统: 一行分成 12 列 div.row div.col-md-12 div.col-xs-12 <div class="row&qu ...

  8. 解决docker启动错误 error creating overlay mount to /var/lib/docker/overlay2

    原文 最近在centos7.1使用docker运行redis镜像,出现下面的错误: /usr/bin/docker-current: Error response from daemon: error ...

  9. 如何在vscode里面调试js和node.js

    一般大家调试都是在浏览器端调试js的,不过有些时候也想和后台一样在代码工具里面调试js或者node.js,下面介绍下怎样在vscode里面走断点. 1,用来调试js 一:在左侧扩展中搜索Debugge ...

  10. COGS2217 papertask

    传送门 以前看到这题的时候觉得是道好题啊……然而今天没多久就做出来了= =(装B 表示并没有看懂其他人写的是什么做法,感觉我的做法好奇怪…… 我的做法是这样的: 首先给括号配对,不难发现所有括号串要么 ...