思路–暴力
因为digit最长为4,所以直接进行模拟,可以得出最终的答案,时间和空间开销比较大,并且会有很多的
代码–暴力
class Solution {
String[][] letter = new String[][]{
{"a","b","c"},
{"d","e","f"},
{"g","h","i"},
{"j","k","l"},
{"m","n","o"},
{"p","q","r","s"},
{"t","u","v"},
{"w","x","y","z"}
};
public List<String> letterCombinations(String digits) {
List<String> ans = new ArrayList<>();
int len = digits.length();
int[] d = new int[4];
for (int i=0;i<len;i++)
d[i] = digits.charAt(i)-'0';
if (d[0]==0)
return ans;
for (int i = 0 ;i<letter[d[0]-2].length;i++)
{
String cur = letter[d[0]-2][i];
if (d[1]!=0){
for (int j = 0 ;j<letter[d[1]-2].length;j++)
{
if (d[2]!=0){
for (int k = 0 ;k<letter[d[2]-2].length;k++)
{
if (d[3]!=0){
for (int l = 0 ;l<letter[d[3]-2].length;l++)
{
ans.add(cur+letter[d[1]-2][j]+letter[d[2]-2][k]+letter[d[3]-2][l]);
}
}
else
ans.add(cur+letter[d[1]-2][j]+letter[d[2]-2][k]);
}
}
else
ans.add(cur+letter[d[1]-2][j]);
}
}
else
ans.add(cur);
}
return ans;
}
}
思路–回溯
思路都是一样的,就是模拟排列组合的过程,只不过这里使用了回溯方法,更加简洁高效。
详情见代码注释。
代码–回溯
class Solution {
String[][] letter = new String[][]{
{"a","b","c"},
{"d","e","f"},
{"g","h","i"},
{"j","k","l"},
{"m","n","o"},
{"p","q","r","s"},
{"t","u","v"},
{"w","x","y","z"}
};
List<String> ansLetter = new ArrayList<>();
StringBuffer sb = new StringBuffer();
public List<String> letterCombinations(String digits) {
int len = digits.length();
if (len==0)//特殊情况判定
return ansLetter;
backTrack(digits, 0);//回溯
return ansLetter;
}
public void backTrack(String digits, int index)
{
if (sb.length() == digits.length())
{
ansLetter.add(sb.toString());
return;
}
//找到对应的字母数组
String[] val = letter[digits.charAt(index)-'0'-2];
for (String i : val)
{
//回溯法的基本套路 选择、回溯、退出选择
//选择
sb.append(i);
//继续向下回溯
backTrack(digits,index+1);
//退出选择--这一步的目的是保持StringBuffer的内容不变,以进行下一个元素的回溯
sb.deleteCharAt(sb.length()-1);
}
}
}