Problem description:
A message contain letters form A-Z is being encoded to numbers using the following mapping:
‘A’ -> 1
‘B’ -> 2‘Z’ -> 26
Given an encoded message containing digits, determine the total number of ways of to decode it.
For example, Given encoded message “12”, it could be decoded as “AB”(1 2) or “L”(12).
So the number of ways decoding “12” is 2.
解题思想:
动态规划
这道题最后问是整个字符串可以有几种解码方式,考虑第i
位的解码问题,当我们考虑第i
位的时候,这时候第i
位可以有两种情况:
- 当第
i
位能和它前面的一位组成一个合法的两位数(10到26)这个时候dp[i]
的值和dp[i-2]
的值是一样的,也就是说i-2
有多少种解码方法,与之对应i
就有多少种解码方法 - 当第
i
位单独可以自己解码的时候,dp[i]
的值和dp[i-1]
的值是一样的,也就是说i-1
有多少种解码方法,与之对应i
就有多少种解码方法
注意代码里面的两个if
是并列的,有可能都会执行的(当第i
位不但可以两位数解码,而且也可以单独一位解码的时候,两个if
都会执行的)
public class Solution {
public int numDecodings(String s) {
if(s.length() == 0) return s.length();
int[] dp = new int[s.length() + 1];
dp[0] = 1;
dp[1] = s.charAt(0) == '0' ? 0 : 1;// 如果第一位是0,则无法解码
for(int i = 2; i <= s.length(); i++){
// 如果字符串的第i-1位和第i位能组成一个10到26的数字,此时的解码方式是和`i-2`的解码方式是一样多的
if(Integer.parseInt(s.substring(i-2, i)) <= 26 && Integer.parseInt(s.substring(i-2, i)) >= 10){
dp[i] += dp[i - 2];
}
// 如果字符串的第i-1位和第i位不仅能组成有效二位数字而且也可以单独来解码,当单独解码时候,当前解码的方式数目和`i-1`位的解码方式是一样多的
if(Integer.parseInt(s.substring(i-1, i)) != 0){
dp[i] += dp[i - 1];
}
// 两个`if`执行完成之后,第`i`位的两种解码可能性都分析完了
}
//最后返回整个字符串的解码方式数目
return dp[s.length()];
}
}