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
/*
* @lc app=leetcode id=639 lang=cpp
*
* [639] Decode Ways II
*/
// @lc code=start
class Solution {
public:
int numDecodings(string s) {
const int N = s.length(), M = 1000000007;
vector<long> dp(N + 1, 0);
dp[0] = 1;
if (s[0] == '*') dp[1] = 9;
else if (s[0] != '0') dp[1] = 1;
for (int i = 2; i <= N; ++i) {
const auto c = s[i - 1];
if (c == '*') {
dp[i] = dp[i - 1] * 9;
switch (s[i - 2]) {
case '1':
dp[i] += dp[i - 2] * 9;
break;
case '2':
dp[i] += dp[i - 2] * 6;
break;
case '*':
dp[i] += dp[i - 2] * 15;
default:
break;
}
} else {
if (c != '0') dp[i] = dp[i - 1];
switch (s[i - 2]) {
case '1':
dp[i] += dp[i - 2];
break;
case '2':
if (c <= '6') dp[i] += dp[i - 2];
break;
case '*':
if (c <= '6') dp[i] += dp[i - 2] * 2;
else dp[i] += dp[i - 2];
default:
break;
}
}
dp[i] %= M;
}
return (int)dp[N];
}
};
// @lc code=end
class Solution {
public int numDecodings(String s) {
int mod = 1000000007;
long[] f = new long[s.length() + 1];
f[0] = 1;
if (s.charAt(0) == '0') {
return 0;
}
f[1] = s.charAt(0) == '*' ? 9 : 1;
for (int i = 2; i <= s.length(); i++) {
char first = s.charAt(i - 2);
char sec = s.charAt(i - 1);
// f[i - 1]
if (sec == '*') {
f[i] += 9 * f[i - 1]; // 1 ~ 9
} else if (sec > '0') {
f[i] += f[i - 1];
}
if (first == '*') {
if (sec == '*') {
f[i] += 15 * f[i - 2]; // 11 ~ 19, 21 ~ 26: 15
} else if (sec <= '6') {
f[i] += 2 * f[i - 2]; // first = 1, 2
} else {
f[i] += f[i - 2]; // first = 1;
}
} else if (first == '1') {
if (sec == '*') {
f[i] += 9 * f[i - 2];
} else {
f[i] += f[i - 2];
}
} else if (first == '2') {
if (sec == '*') {
f[i] += 6 * f[i - 2];
} else if (sec <= '6') {
f[i] += f[i - 2];
}
}
f[i] %= mod;
}
return (int)f[s.length()];
}
}
时间复杂度还是O(N), 空间可以O(1), 因为实际只用了i - 1和i - 2.