题目描述
给定一个数字,按照如下规则翻译成字符串:1 翻译成“a”,2 翻译成“b”... 26 翻译成“z”。一个数字有多种翻译可能,例如 12258 一共有 5 种,分别是 abbeh,lbeh,aveh,abyh,lyh。实现一个函数,用来计算一个数字有多少种不同的翻译方法。
解题思路
public int numDecodings(String s) {
if (s == null || s.length() == 0)
return 0;
int n = s.length();
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = s.charAt(0) == '0' ? 0 : 1;
for (int i = 2; i <= n; i++) {
int one = Integer.valueOf(s.substring(i - 1, i));
if (one != 0)
dp[i] += dp[i - 1];
if (s.charAt(i - 2) == '0')
continue;
int two = Integer.valueOf(s.substring(i - 2, i));
if (two <= 26)
dp[i] += dp[i - 2];
}
return dp[n];
}
使用动态规划:
从后往前计算:
public class NumberTranslateToStr {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
String str = sc.next();
int n = str.length();
int[] dp = new int[n];
cal(dp, str, 0);
System.out.println("结果:"+dp[0]);
}
public static void cal(int[] dp, String str, int i) {
if (i > str.length() - 1) {
return;
}
if (i == str.length() - 1) {
dp[i] = 1;
return;
}
cal(dp, str, i+1);
if (i == str.length() - 2) {
if (Integer.valueOf(str.substring(i, str.length())) < 26) {
dp[i] = 2;
return;
} else {
dp[i] = 1;
return;
}
}
if (i < str.length() - 2) {
if (Integer.valueOf(str.substring(i, i + 2)) < 26) {
dp[i] = dp[i + 1] + dp[i+2];
return;
} else {
dp[i] = dp[i + 1];
return;
}
}
}
}
改进了一下,从前往后了:
public class NumberTranslateToStr2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
String str = sc.next();
int n = str.length();
int[] dp = new int[n];
cal(dp, str.split(""), n-1);
System.out.println("结果:"+dp[n-1]);
}
public static void cal(int[] dp, String[] str, int i) {
if(i==0){
dp[i]=1;
return;
}
if(i==1){
if(Integer.valueOf(str[0]+str[1])<26){
dp[i]=2;
}else{
dp[i]=1;
}
}
cal(dp,str,i-1);
if(i>1){
if(Integer.valueOf(str[i-1]+str[i])<26){
dp[i]=dp[i-1]+dp[i-2];
return;
}else{
dp[i]=dp[i-1];
return;
}
}
}
}
自己的方法没考虑0的情况