思路:动态规划,就是去穷举所有的情况。
首先将数字变为 char 数组,
每一次传入两个下标(index1,index2)所对应的数字,我们可以讲两个数字分开,把单个数字翻译成一个字母,也可以尝试两个数字翻译成一个字母。
最后当index发生越界的时候,那么就证明已经到了数组的尾部了,相当于这一种情况已经被列举出来,我们将这种情况保存在一个HashSet中,最后所有的递归结束时,HashSet的size,就是所有的情况。
class Solution {
//保存所有的翻译情况
HashSet<String> set = new HashSet();
//26个数字对应的字符
char[] numberOfWords = new char[26];
public int translateNum(int num) {
//如果这个数字是个位数,那么就只有一种情况。至于<0,默认为一种翻译情况
if(num < 0 || (num / 10) <= 0) return 1;
//26个数字对应的字符赋值
for(int i = 0;i < 26 ;i ++){
numberOfWords[i] = (char)('a'+i);
}
//把数字转为char数组,方便操作
char[] number = String.valueOf(num).toCharArray();
//利用StringBuilder去保存翻译的情况
StringBuilder sb = new StringBuilder();
countCase(number,sb,0,1);
return set.size();
}
private void countCase(char[] number,StringBuilder sb ,int index1 ,int index2){
//表示当前这种情况翻译结束
if(index1 > number.length-1) {
set.add(sb.toString());
return ;
}
//首先保存当前的翻译情况
String temp = sb.toString();
//单个数字翻译
sb.append(numberOfWords[ number[index1]- '0' ] );
countCase(number,sb,index2,index2+1 );
if(index2 < number.length){
//两个数字当作单个字符来翻译
StringBuilder sb1 = new StringBuilder();
sb1.append(temp);
int firstNumber = number[index1] - '0';
if(firstNumber > 0){
int stringNumber = (number[index1] - '0')*10 + number[index2]-'0';
if(stringNumber < 26){
sb1.append(numberOfWords[stringNumber]);
countCase(number,sb1,index2+1,index2+2);
}
}
}
}
}
大佬简介思路:斐波那契 + 动态规划
class Solution {
public int translateNum(int num) {
//将数字转为char数组
char[] sc = String.valueOf(num).toCharArray();
int n = sc.length;
int[] f = new int[n + 1];
f[0] = 1;
for (int i = 1; i <= n; i++) {
if (sc[i - 1] >= '0' && sc[i - 1] <= '9') {
f[i] += f[i - 1];
}
if (i > 1) {
int a = (sc[i - 2] - '0') * 10 + (sc[i - 1] - '0');
if (a >= 10 && a <= 25) {
f[i] += f[i - 2];
}
}
}
return f[n];
}
}