1.题目
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number
2.自己想法
先放自己想法的代码,接下来在解释,这个有问题,准备再力扣中删除重写,先把代码复制到这里
- 自己开始这样写,只能完成两个数字的,完不成其它的,所以进行更换
class Solution {
public List<String> letterCombinations(String digits) {
String s[] = new String[digits.length()];
List<String> list = new ArrayList<>();
if(s.length == 0 ) return list;
//写一个switch case
for(int i = 0 ; i <digits.length();i++)
{
switch(digits.charAt(i))
{
case '2':s[i] = "abc";break;
case '3':s[i] = "def";break;
case '4':s[i] = "ghi";break;
case '5':s[i] = "jkl";break;
case '6':s[i] = "mno";break;
case '7':s[i] = "pqrs";break;
case '8':s[i] = "tuv";break;
case '9':s[i] = "wxyz";break;
}
}
if(s.length == 1){
for(int i = 0 ; i <s[0].toCharArray().length;i++)
{
String s1 = ""+s[0].toCharArray()[i];
list.add(s1);
}
return list;
}
//获取到s了
for(int i = 0 ; i <s.length-1;i++)
{
char[] oneStr = s[i].toCharArray();
char[] secStr = s[i+1].toCharArray();
for(int j = 0 ; j<oneStr.length;j++)
{
for(int k = 0 ; k <secStr.length;k++)
{
String ss = ""+oneStr[j]+secStr[k];
list.add(ss);
}
}
}
return list;
}
}
if(s.length == 1){
for(int i = 0 ; i <s[0].toCharArray().length;i++)
{
String s1 = ""+s[0].toCharArray()[i];
list.add(s1);
}
}
//获取到s了
for(int i = 0 ; i <s.length-2;i++)//遍历s
{
//String ss1 = ""+s[0].toCharArray()[i];
//list.add(ss1);
list =combineList(s[i],s[i+1]);
}
return list;
}
//其实他们就是两两组合二乘的字符串 ,别怕嗄
public List<String> combineList(String s1,String s2)
{
char[] s1char = s1.toCharArray();
char[] s2char = s2.toCharArray();
List<String> li = new ArrayList<>();
for(int i = 0 ; i < s1char.length; i++)
{
for(int j = 0 ; j<s2char.length;j++)
{
String s1s2 = ""+s1char[i]+s2char[j];
li.add(s1s2);
}
}
return li;
}
}
把第一次的代码改进后,写成这个样子了,发现还是有问题;
- 问题,list不能重复再使用,所以list还是只能返回两个
- 传入的参数必须应该是 一个list 一个string 返回list 这样list可以重复使用,这样才可以
答题思路就是获取到那些字母对应的数字,然后调取方法两两组合,最后返回list;
if(s.length == 1){
for(int i = 0 ; i <s[0].toCharArray().length;i++)
{
String s1 = ""+s[0].toCharArray()[i];
list.add(s1);
}
return list;
}
//获取到s了
for(int i = 0 ; i <s.length;i++)//遍历s
{
list =combineList(list,s[i]);
}
return list;
}
//其实他们就是两两组合二乘的字符串 ,别怕嗄
public List<String> combineList(List<String> s1,String s2)
{
List<String> str = new ArrayList<>();
for(int i = 0 ; i < s2.length();i++)
{
if(s1.isEmpty())
{
str.add(s2.substring(i,i+1));
}else
{
for(String s : s1)
{
str.add(s+s2.substring(i,i+1));
}
}
}
return str;
}
其中combineList 自己写还是有问题,看了一下别人的方法,才写出来。方法思路
- 如果 list是空的,就是第一次,那么把s2的元素一个一个的加入str中
- 不是空的,那么取出list的每一个元素,再把string的每个元素加入其中
举个例子,list是['a','b','c'];string是‘wxyz’,那么循环就是 aw ax ay az bw bx by bz ...这样一直加下去
3.总结
自己感觉这篇博客写的有点乱,是因为在写的过程中,自己的想法有问题,想删掉,但是没哪里记的,就把代码放到博客里来了,最后才写成,开始的思想是写的两个组合,但是有三个数字的测试用例才明白这样写是有问题的,后来才采用两两组合的方式,但是自己的问题就在两两组合的时候,有点懵了不会写了,其中 substring的运用不熟练嗄。看了别人的代码,才知道写两两组合。
还有就是我看了下力扣提交的结果中,我这种方式已经属于第二梯队里的正态分布了,说明这个方法还有很大的改正地方。好不容易写出来。。。(继续改进嗄,哈哈自己写出来都不想看答案了)