持续刷题第7天 !
今天我们继续刷Leetcode 热题 HOT 100,日复一日,相信自己,一定会有进步。如果一个人刷题太孤独了,欢迎加群每日一题算法群,让我们大家一起监督,一起成长。
Leetcode - 17.电话号码的排列组合
题目描述:
给定一个仅包含数字 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 (最长无重复子串,两个有序数组的中位数)
扫码加入我们