题目描述
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 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’.
思路
动态规划。前一个字符和后一个字符能组成多少种情况,得到当前种类数和之前种类数的关系。有*号的时候关系是乘法,不是加法。
查了好久的if。badcase调试=。=
代码
class Solution {
public:
int numDecodings(string s) {
if (s[0] == '0') return 0;
int n = s.length();
vector<long long> dp(n+1, 0);
if (s[0] == '*') dp[0] = 9;
else if (s[0]-'0' >= 1 && s[0]-'0' <= 9) dp[0] = 1;
int MOD = 1e9+7;
for (int i=1; i<n; ++i) {
if (s[i] == '*') {
if (s[i-1] == '*') {
dp[i] = dp[i-1] * 9 + (i > 1 ? dp[i-2] : 1) * 15;
}else {
int num = s[i-1] - '0';
if (num == 0) dp[i] = dp[i-1] * 9;
else if (num == 1) dp[i] = dp[i-1] * 9 + (i>1 ? dp[i-2] : 1) * 9;
else if (num == 2) {
dp[i] = dp[i-1] * 9 + (i>1 ? dp[i-2] : 1) * 6;
}
else dp[i] = dp[i-1] * 9;
}
}else {
if (s[i-1] == '*') {
int num = s[i] - '0';
if (num == 0) {
dp[i] = (i>1 ? dp[i-2] : 1) * 2;
}else {
dp[i] = dp[i-1] + (i>1 ? dp[i-2] : 1) * (num <= 6 ? 2 : 1);
}
}else {
int num1 = s[i-1] - '0';
int num2 = s[i] - '0';
if (num1 == 0 && num2 != 0) {
dp[i] = dp[i-1];
}else {
int num = num1 * 10 + num2;
if (num >= 10 && num <= 26) {
if (num2 != 0) dp[i] = dp[i-1] + (i>1 ? dp[i-2] : 1);
else dp[i] = (i > 1 ? dp[i-2] : 1);
}else if (num2 != 0) {
dp[i] = dp[i-1];
}
}
}
}
dp[i] = dp[i] % MOD;
}
return dp[n-1];
}
};