leetcode:639. 解码方法 II

题目来源

题目描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值