标签:shm 不可 两数之和 正则匹配 成长 全排列 char 状态 答案
持续刷题第7天 !今天我们继续刷Leetcode 热题 HOT 100,日复一日,相信自己,一定会有进步。如果一个人刷题太孤独了,欢迎加群每日一题算法群,让我们大家一起监督,一起成长。
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母
注意:答案中不可以包含重复的三元组。
输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
怎么解呢?
这道题主要考察的还是搜索,由于一个字母对应的是多种方案,那么多个字母组合,相当于是由各自方案的组合,你这个例子23为例,那么23在2中选一个字母,在2中选一个字母,这样的话就组成了一种可能的方式,由于每个数字代表的,字母个数为三个或四个,那么相当于组合后的方式是等同于字母个数相乘。
例如23,这是3个字母和3个字母相乘,一共是九种方案。
编辑的时候想到: 状态动态规划,就是利用二进制数去代表每一个可以选的方式,假设现在是二代表的是ABC三个字母,那么我用100表示选的是a,表示选的第一个字母,010代表选b,001代表选c.有那么一点状态压缩的意思,后面说到状态DP会详细提到,这里就不用啦。
这道题目其实是可以采用深度优先搜索中不用回溯的做法,也其实是深度优先搜索的入门题,也就是说,当前的选择不会因为上一选择而所受到影响,因为每次他要选字母都可以选。
后面我们会讲到,由于上一种上一个数字选,那么这个数字不能选,所以需要有一种回溯的做法,可以参考全排列1,全排列2这两道题目。
那么我们在这里采用广度优先搜索的方式,利用队列即可完成。
class Solution {
Map<String, String> phone = new HashMap<String, 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");
}};
private List<String> output = new LinkedList<>();
public List<String> letterCombinations(String digits) {
if(digits.length()==0)//长度为0 返回
return output;
output.add("");//初始化
for(int i=0;i<digits.length();i++){//遍历每一个数字
int N=output.size();//得到队列长度,需要一次弹出往后面加东西
while(N-->0){
String tp=output.get(0);//得到队首
String state=phone.get(String.valueOf(digits.charAt(i)));//得到下一层要的加的字母
for(int k=0;k<state.length();k++)//遍历所有字母,往队首加上去 然后加入队列中
output.add(tp+state.charAt(k));
output.remove(0);//将队首弹出,意味着这个加工完成
}
}
return output;
}
}
LeetCode day 1 题号1、2(两数之和,两数相加)
LeetCode day 2 题号 3、4 (最长无重复子串,两个有序数组的中位数)
LeetCode day3 题号5 (最长回文子串)
LeetCode day 4 10.正则匹配
LeetCode day 5 盛最多水的容器(双指针)
LeetCode day 6 三数之和=两数之和plus
扫码加入我们
标签:shm 不可 两数之和 正则匹配 成长 全排列 char 状态 答案
原文地址:https://blog.51cto.com/15054042/2563996