解法 动态规化
以12256为例从左边开始翻译可以分为两个子问题:翻译1,2256,翻译12,256;2256可以分解为翻译2,256 | 22,56。256可以分解为翻译2,56。由上分析可以使用递归求解但是存在重复部分“56”,所以考虑由下至上解决问题,这样可以消除子问题假设 f ( i ) f(i) f(i)是第i个数开始存在的翻译数则 f ( i ) = f ( i + 1 ) + g ( i , i + 1 ) f ( i + 2 ) f(i) = f(i+1) + g(i,i+1)f(i+2) f(i)=f(i+1)+g(i,i+1)f(i+2)其中 g ( i , i + 1 ) g(i,i+1) g(i,i+1)表示第i与第i+1个数合并后在10~25的范围内为1否则为0。代码如下:
class Solution {
public int translateNum(int num) {
if(num < 0) return 0;
String numberInString = String.valueOf(num);
return translateNum(numberInString);
}
private int translateNum(String numberInString) {
int len = numberInString.length();
// 记录f(i), 从第i个数字开始有多少种翻译方式
int[] counts = new int[len];
int count = 0;
for(int i = len - 1; i >= 0; --i) {
if(i < len - 1)
// f(i) = f(i+1)
count = counts[i+1];
else
// f(i) = 1, 末尾数字只有一种翻译方法
count = 1;
if(i < len - 1) {
int digit1 = numberInString.charAt(i) - '0';
int digit2 = numberInString.charAt(i+1) - '0';
int combine = digit1 * 10 + digit2;
if(combine <= 25 && combine >= 10) {
if(i < len - 2)
// f(i) = f(i+1) + f(i+2)
count += counts[i+2];
else
count+=1;
}
}
counts[i] = count;
}
count = counts[0];
return count;
}
}