A message containing letters from A-Z 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 10^9 + 7.
Example
Example 1
Input: "*"
Output: 9
Explanation: You can change it to "A", "B", "C", "D", "E", "F", "G", "H", "I".
Example 2
Input: "1*"
Output: 18
Notice
- The length of the input string will fit in range [1, 10^5].
- The input string will only contain the character
*
and digits0
-9
.
思路:跟decode way I没有多少区别,只是要分情况讨论十位和个位的情况;注意dp数组一定要用long;c2 分别有1,2,3,*, 然后根据这四种情况,c1又有很多种情况,分别讨论;
class Solution {
public int numDecodings(String s) {
if(s == null || s.length() == 0) {
return 0;
}
int MOD = 1000000007;
char[] ss = s.toCharArray();
int n = s.length();
long[] dp = new long[n + 1];
dp[0] = 1;
for(int i = 1; i <= n; i++) {
dp[i] += dp[i - 1] * count1(ss[i - 1]);
if(i - 2 >= 0) {
dp[i] += dp[i - 2] * count2(ss[i - 2], ss[i - 1]);
}
dp[i] = dp[i] % MOD;
}
return (int)dp[n] % MOD;
}
//count 1 digit;
private int count1(char c) {
if(c == '0') {
return 0;
} else if('1' <= c && c <= '9') {
return 1;
} else if(c == '*') {
return 9;
} else {
return 0;
}
}
// count 2 digits;
// c2 => 0,1,2,3,*;
private int count2(char c2, char c1) {
if(c2 == '0') {
return 0;
} else if(c2 == '1') {
if('0' <= c1 && c1 <= '9') {
return 1;
} else {
// c1 == '*';
return 9;
}
} else if(c2 == '2') {
if('0' <= c1 && c1 <= '6') {
return 1;
} else if(c1 >= '6') {
return 0;
} else {
// c1 == '*'
return 6;
}
} else if('3' <= c2 && c2 <= '9') {
return 0;
} else {
// c2 == '*';
if('0' <= c1 && c1 <= '6') {
return 2;
} else if('7' <= c1 && c1 <= '9') {
return 1;
} else {
// c2 == '*' c1 == '*'
// c2 = 1, 9
// c2 = 2, 6
return 15;
}
}
}
}