每天一道算法题系列:
来源:力扣(LeetCode)
本题链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
来源是力扣,大家喜欢可以去力扣中文网做相应的其他的题,某浏览器直接搜力扣即可。
本题难度是中等
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
package com.example.demo.likou11;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
*
* 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
*
* 示例:
*
* 输入:"23"
* 输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
*
*
*/
public class LetterCombinations {
/*
不得不说把这道题做出来的人真的厉害,反正我差(*一个太阳系那么大*)点就把它做出来了
我最开始以为这道题可以用贪心算法的方式,但是发现还是不行,还需要用到递归
然后我不是很懂这块,最后再看前人的做法的时候,勉强算是懂了,现在写下我的思路
*/
public static List<String> letterCombinations(String digits) {
List<String> res = new ArrayList<>();
if (digits == null || "".equals(digits)) {
return res;
}
//一般这样的情况需要枚举所有的种类,和之前做过的罗马数转数字有点像
Map<Character, String> phoneMap = new HashMap<Character, String>() {{
put('2', "abc");put('3', "def");
put('4', "ghi");put('5', "jkl");
put('6', "mno");put('7', "pqrs");
put('8', "tuv");put('9', "wxyz");
}};
//进入递归方法
doSomething(res, phoneMap, digits, new StringBuffer(), 0);
return res;
}
private static void doSomething
(List<String> res, Map<Character, String> phoneMap, String digits, StringBuffer sb, int index) {
/*
这里主要是为了控制到最底层,比如说2:a,b,c和3:d,e,f和4:g,h,j
当我们从2的a一直加到3的d,4的g的时候,就已经到了最底了,不会再
往后面加了,需要返回去,再重新到a,d,h;
然后再进入循环,再重新到a,d,j
*/
if (index == digits.length()) {
res.add(sb.toString());
} else {
//取第一个数,然后再进行for循环
char c = digits.charAt(index);
String s = phoneMap.get(c);
for (int i = 0; i < s.length(); i++) {
//这里采用stringBuffer的好处是不用一直new,可以直接无脑后面啊append
//顺口提一句,stringBuffer是线程安全的哦,再append的时候synchronized修饰了
sb.append(s.charAt(i));
doSomething(res, phoneMap, digits, sb, index + 1);
/*
StringBuffer sb = new StringBuffer();
sb.append("a");
sb.append("b");
sb.append("c");
sb.append("d");
sb.append("e");
System.out.println(sb.toString());
sb.deleteCharAt(1);
System.out.println(sb.toString());
输出结果
abcde
acde
*/
//如果不删除 , 就变成了adg, adgh, adghi, adghieg, adghiegh, adghieghi
sb.deleteCharAt(index);
}
}
}
public static void main(String[] args) {
String s = "234";
System.out.println(letterCombinations(s));
}
}
上一篇文章:每天一道算法题系列十六之最接近的三数之和
请继续关注我,如果后面不忙了,会写一系列关于的设计模式等等等的文章。
如果本篇内容有问题,请第一时间联系我,我会第一时间修改。
谢谢大家。