2020年8月26日 电话号码的字母组合 letterCombinations
class Solution {
public List<String> letterCombinations(String digits) {
}
}
解题思路:
这道题貌似没有什么技巧可言,可以使用穷举的方式列举出所有可能的情况一共就8种,将原来的字符串复制并且加上新的字母,这道题可能考察的是不同字符串操作的效率吧。
代码实现:
看起来这道题有一些巧妙的解决方案,找一找有没有什么优化的方案
final char[] char2={'a','b','c'};
final char[] char3={'d','e','f'};
final char[] char4={'g','h','i'};
final char[] char5={'j','k','l'};
final char[] char6={'m','n','o'};
final char[] char7={'p','q','r','s'};
final char[] char8={'t','u','v'};
final char[] char9={'w','x','y','z'};
public List<String> letterCombinations(String digits) {
List<String> res=new ArrayList<>();
int len=digits.length();
if(len==0)
return res;
res.add("");
for (int i=0;i<len;i++){
if (digits.charAt(i)=='2'){
List<String> newList=new ArrayList<>();
for (String re : res) {
for (char c : char2) {
newList.add(re+c);
}
}
res=newList;
}
else if (digits.charAt(i)=='3'){
List<String> newList=new ArrayList<>();
for (String re : res) {
for (char c : char3) {
newList.add(re+c);
}
}
res=newList;
}
else if (digits.charAt(i)=='4'){
List<String> newList=new ArrayList<>();
for (String re : res) {
for (char c : char4) {
newList.add(re+c);
}
}
res=newList;
}
else if (digits.charAt(i)=='5'){
List<String> newList=new ArrayList<>();
for (String re : res) {
for (char c : char5) {
newList.add(re+c);
}
}
res=newList;
}
else if (digits.charAt(i)=='6'){
List<String> newList=new ArrayList<>();
for (String re : res) {
for (char c : char6) {
newList.add(re+c);
}
}
res=newList;
}
else if (digits.charAt(i)=='7'){
List<String> newList=new ArrayList<>();
for (String re : res) {
for (char c : char7) {
newList.add(re+c);
}
}
res=newList;
}
else if (digits.charAt(i)=='8'){
List<String> newList=new ArrayList<>();
for (String re : res) {
for (char c : char8) {
newList.add(re+c);
}
}
res=newList;
}
else if (digits.charAt(i)=='9'){
List<String> newList=new ArrayList<>();
for (String re : res) {
for (char c : char9) {
newList.add(re+c);
}
}
res=newList;
}
}
return res;
}
优化思路1:
我觉得我之前的算法大多数时间都消耗在了字符串的拼接和构建链表对象和遍历链表上了,所以要减少耗费在这上面的时间。
优化1,使用数组代替字符串进行操作,这样可以提高字符串的操作效率
优化2,使用进制的思想,根据数字所在的位置以及数字能够代表的字符种类个数
经过长时间的计算,终于得到下面的代码,区别就在于每一个数字都可以直接通过他的位置和所代表的的字符在返回值数组的对应位置填上对应的值。并且使用了数组来代替字符串的操作
public List<String> letterCombinations(String digits) {
int len=digits.length();
if (len==0)
return new ArrayList<>();
int num=1;
for (int i=0;i<len;i++){
if (digits.charAt(i)=='7'||digits.charAt(i)=='9'){
num*=4;
}
else num*=3;
}
//结果集
char[][] res=new char[num][len];
int num2=num;
for (int i=0;i<len;i++){
if (digits.charAt(i)=='7'||digits.charAt(i)=='9'){
num2/=4;
}
else num2/=3;
for (int j=0;j<num;j++){
if (digits.charAt(i)=='2'){
res[j][i]=char2[(j/num2)%3];
}else if (digits.charAt(i)=='3'){
res[j][i]=char3[(j/num2)%3];
}else if (digits.charAt(i)=='4'){
res[j][i]=char4[(j/num2)%3];
}else if (digits.charAt(i)=='5'){
res[j][i]=char5[(j/num2)%3];
}else if (digits.charAt(i)=='6'){
res[j][i]=char6[(j/num2)%3];
}else if (digits.charAt(i)=='7'){
res[j][i]=char7[(j/num2)%4];
}else if (digits.charAt(i)=='8'){
res[j][i]=char8[(j/num2)%3];
}else if (digits.charAt(i)=='9'){
res[j][i]=char9[(j/num2)%4];
}
}
}
List<String> reslist=new LinkedList<>();
for (int i=0;i<num;i++){
reslist.add(new String(res[i]) );
}
return reslist;
}