题目来源
题目描述
class Solution {
public:
int numDecodings(string s) {
}
};
题目解析
class Solution {
public:
int numDecodings(string s) {
int n = s.size(), M = 1e9 + 7;
vector<long> dp(n + 1, 0);
dp[0] = 1;
if (s[0] == '0') return 0;
dp[1] = (s[0] == '*') ? 9 : 1;
for (int i = 2; i <= n; ++i) {
if (s[i - 1] == '0') {
if (s[i - 2] == '1' || s[i - 2] == '2') {
dp[i] += dp[i - 2];
} else if (s[i - 2] == '*') {
dp[i] += 2 * dp[i - 2];
} else {
return 0;
}
} else if (s[i - 1] >= '1' && s[i - 1] <= '9') {
dp[i] += dp[i - 1];
if (s[i - 2] == '1' || (s[i - 2] == '2' && s[i - 1] <= '6')) {
dp[i] += dp[i - 2];
} else if (s[i - 2] == '*') {
dp[i] += (s[i - 1] <= '6') ? (2 * dp[i - 2]) : dp[i - 2];
}
} else { // s[i - 1] == '*'
dp[i] += 9 * dp[i - 1];
if (s[i - 2] == '1') dp[i] += 9 * dp[i - 2];
else if (s[i - 2] == '2') dp[i] += 6 * dp[i - 2];
else if (s[i - 2] == '*') dp[i] += 15 * dp[i - 2];
}
dp[i] %= M;
}
return dp[n];
}
};
- 下面版本对大数取余了,但是超时
class Solution {
long long Mod = 1e9 + 7;
std::map<int, long long> cache;
//1 <= s.length <= 10^5
// s[i] 是 0 - 9 中的一位数字或字符 '*'
// * 不能替代0 !!!!!!!!!!!
long long process(string s, int idx){
if(idx == s.size()){
return 1;
}
if(s[idx] == '0'){
return 0;
}
if(cache.count(idx)){
return cache[idx];
}
if(s[idx] == '*'){
long long p1 = 9 * process(s, idx + 1) % Mod; // 独立作为一位 1, 2, 3, ... 9
long long p2 = 0;
if(idx + 1 == s.size()){
p2 = 0;
}else if(s[idx + 1] != '*'){ //
if(s[idx + 1] >= '0' && s[idx + 1] <= '6'){ // *0, *6, *只能是1, 2 // 10, 20
p2 = 2 * process(s, idx + 2) % Mod;
}else{ // *7 // 17, 18, 16
p2 = 1 * process(s, idx + 2) % Mod;
}
}else{ // ** // 11 --- 19, 21--26 // 9 + 6
p2 = 15 * process(s, idx + 2) % Mod;
}
return cache[idx] = (p1 + p2) % Mod;
}
// // 2, 8, 3 9 ---> 1
long long p1 = process(s, idx + 1) % Mod;
long long p2 = 0;
if(idx + 1 == s.size()){
p2 = 0;
}else if(s[idx + 1] == '*'){ // 只考虑两位的
if(s[idx] == '1'){ // 1* // 11 - 19
p2 = 9 * process(s, idx + 2) % Mod;
}else if(s[idx] == '2'){ // 2*xxxx
p2 = 6 * process(s, idx + 2) % Mod;
}else{ // 3*xxxx
p2 = 0;
}
}else{
if(s[idx] == '1'){ // 1n
p2 = process(s, idx + 2) % Mod;
}else if(s[idx] == '2'){ //2n
if(s[idx + 1] >= '0' && s[idx + 1] <= '6'){
p2 = process(s, idx + 2) % Mod;
}
}else{ // 3n
p2 = 0;
}
}
return cache[idx] = (p1 + p2)%(Mod);
}
public:
int numDecodings(string s) {
return (int)process(s, 0);
}
};
- 下面版本没有对大数取余
class Solution {
int process(string str, int i){
if(i == str.size()){
return 1;
}
if(str[i] == '0'){
return 0;
}
// str[index]有字符且不是'0'
if(str[i] != '*'){
// str[index] = 1~9
int p1 = process(str, i + 1);
if(i + 1 == str.size()){
return p1;
}
if(str[i + 1] != '*'){
int num = (str[i] - '0') * 10 + str[i + 1] - '0';
int p2 = 0;
if(num < 27){
p2 = process(str, i + 2);
}
return p1 + p2;
}
// str[i+1] == '*'
// i i+1 -> 一起转 1* 2* 3* ...9*
int p2 = 0;
if(str[i] < '3'){
p2 = process(str, i + 2) * (str[i] == '1' ? 9 : 6);
}
return p1 + p2;
}
// str[i] == '*' 1~9
int p1 = 9 * process(str, i + 1); // i 单转 9种
if(i + 1 == str.size()){
return p1;
}
if(str[i + 1] != '*'){
// * 0 10 20
// * 1 11 21
// * 2 12 22
// * 3 13 23
// * 6 16 26
// * 7 17
// * 8 18
// * 9 19
int p2 = (str[i + 1] < '7' ? 2 : 1) * process(str, i + 2);
return p1 + p2;
}else{
// **
// 11~19 9
// 21 ~26 6
// 15
int p2 = 15 * process(str, i + 2);
return p1 + p2;
}
}
public:
int numDecodings(string s) {
return process(s, 0);
}
};