题目:
给定一个数字,我们按照如下规则把它翻译成字符串:0翻译成a,1翻译成b……25翻译成z。一个数字可能有多个翻译。例如,12258有5种不同的翻译,分别是“bccfi”、“bwfi”、“bczi”、“mcfi”和“mzi”,请实现一个函数,用来计算一个数字有多少种不同的翻译方法。
分析:
我们一12258为例分析翻译过程。第一次翻译的时候,有两种选择:选1个数和选2个数,分别对应b和m。可以发现后面的翻译过程,可以看做12258的一个子串进行翻译,翻译过程还是一样的,这是一个递归过程。
我们定义函数f(i)表示从第i位数字开始的不同翻译的数目,那么f(i)=f(i+1)+g(i,i+1)×f(i+2),其中g(i,i+1)表示的第i位和第i+1位拼接的数字是不是在10~25之间,如果在g(i,i+1)的值为1,如果不在,g(i,i+1)的值为0。
通过分析,递归会存在重复的子问题,因此递归不是这个问题的最佳解决方法,递归是自上而下的,我们可以采用自下而上的方法,从最小子问题开始分析,也就是从最右端开始分析,直到最左端停止。
解法:
package com.wsy;
public class Main {
public static void main(String[] args) {
int number = 12258;
char[] chars = String.valueOf(number).toCharArray();
getTranslateCount(chars);
}
public static void getTranslateCount(char[] chars) {
int length = chars.length;
int[] counts = new int[length + 1];// length+1防止越界
for (int i = length - 1; i >= 0; i--) {
if (i == length - 1) {
counts[i] = 1;
} else {
counts[i] = counts[i + 1] + g(i, chars) * counts[i + 2];
}
}
System.out.println("翻译方法有:" + counts[0] + "种");
}
public static int g(int index, char[] chars) {
int number = Integer.parseInt("" + chars[index] + chars[index + 1]);
return number >= 10 && number <= 25 ? 1 : 0;
}
}