A message containing letters from de >A-Zde> is being encoded to numbers using the following mapping way:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
Beyond that, now the encoded string can also contain the character '*', which can be treated as one of the numbers from 1 to 9.
Given the encoded message containing digits and the character '*', return the total number of ways to decode it.
Also, since the answer may be very large, you should return the output mod 109 + 7.
Example 1:
Input: "*" Output: 9 Explanation: The encoded message can be decoded to the string: "A", "B", "C", "D", "E", "F", "G", "H", "I".
Example 2:
Input: "1*" Output: 9 + 9 = 18
Note:
- The length of the input string will fit in range [1, 105].
- The input string will only contain the character '*' and digits '0' - '9'.
使用动态规划的思想,从字符串的最后一位向前计算,数组的每一位表示从这一位往后的子串有多少种Decode方法,递推公式如下
第i字符 | 第i+1字符 | 递推公式 |
0 | 任意 | dp[i] = 0 |
1 | * | dp[i] = dp[i+1] + dp[i+2] * 9 |
1 | 0~9 | dp[i] = dp[i+1] + dp[i+2] |
2 | * | dp[i] = dp[i+1] + dp[i+2] * 6 |
2 | 0~6 | dp[i] = dp[i+1] + dp[i+2] |
2 | 7~9 | dp[i] = dp[i+1] |
3~9 | 任意 | dp[i] = dp[i+1] |
* | * | dp[i] = dp[i+1] * 9 + dp[i+2] * 15 |
* | 0~6 | dp[i] = dp[i+1] * 9 + dp[i+2] * 2 |
* | 7~9 | dp[i] = dp[i+1] * 9 + dp[i+2] |
class Solution {
public int numDecodings(String s) {
int len = s.length();
char[] chs = s.toCharArray();
long[] record = new long[len + 1];
record[len] = 1;
int it = len - 1;
for(; it > -1; it--){
char cur = chs[it];
if(it == len - 1){
if(cur == '*'){
record[it] = 9;
}
else if(cur == '0'){
record[it] = 0;
}
else{
record[it] = 1;
}
continue;
}
char next = chs[it + 1];
if(cur == '0'){
record[it] = 0;
}
else if(cur == '1'){
if(next == '*'){
record[it] = record[it + 1] + record[it + 2] * 9;
}
else{
record[it] = record[it + 1] + record[it + 2];
}
}
else if(cur == '2'){
if(next == '*')
record[it] = record[it + 1] + record[it + 2] * 6;
else if(next >= '0' && next <= '6')
record[it] = record[it + 1] + record[it + 2];
else
record[it] = record[it + 1];
}
else if(cur >= '3' && cur <= '9'){
record[it] = record[it + 1];
}
else{
record[it] += record[it + 1] * 9;
if(next >= '0' && next <= '6')
record[it] += record[it + 2] * 2;
else if(next >= '7' && next <= '9')
record[it] += record[it + 2];
else if(next == '*')
record[it] += record[it + 2] * 15;
}
record[it] %= 1000000007;
}
return (int)record[0];
}
}