639. [C + +] decoding method II

Posted by ganeshcp on Mon, 27 Sep 2021 15:02:16 +0200

Title Description

A message containing the letters A-Z is encoded as follows:

'A' -> 1
'B' -> 2
...
'Z' -> 26
To decode an encoded message, all numbers must be grouped and then mapped back to letters according to the original encoding scheme (there may be many ways). For example, "11106" can be mapped to:

"AAJF" corresponding group (1 10 6)
"KJF" corresponding group (11 10 6)
Note that grouping such as (1 11 06) is invalid because "06" cannot be mapped to "F" because "6" is different from "06".

In addition to the alphanumeric mapping scheme described above, the encoded message may contain '' characters, which can represent any number from '1' to '9' (excluding '0'). For example, the encoding string "1" can represent any one of "11", "12", "13", "14", "15", "16", "17", "18" or "19". Decoding "1 *" is equivalent to decoding any encoded message that the string can represent.

Give you a string s, consisting of numbers and '*' characters, and return the number of methods to decode the string.

Since the number of answers may be very large, the result of 109 + 7 remainder is returned.

Example 1:

Input: s=““
Output: 9
Explanation: this encoded message can represent any one of "1", "2", "3", "4", "5", "6", "7", "8" or "9".
Can be decoded into strings "A", "B", "C", "D", "E", "F", "G", "H" and "I" respectively.
Therefore, there are 9 decoding methods for "" in total.
Example 2:

Input: s = "1 *"
Output: 18
Explanation: this encoded message can represent any one of "11", "12", "13", "14", "15", "16", "17", "18" or "19".
Each message can be decoded by two methods (for example, "11" can be decoded into "AA" or "K").
Therefore, "1 *" has 9 * 2 = 18 decoding methods.
Example 3:

Input: s = "2 *"
Output: 15
Explanation: this encoded message can represent any one of "21", "22", "23", "24", "25", "26", "27", "28" or "29".
"21", "22", "23", "24", "25" and "26" have two decoding methods, but "27", "28" and "29" have only one decoding method.
Therefore, "2 *" has (6 * 2) + (3 * 1) = 12 + 3 = 15 decoding methods.

Tips:

1 <= s.length <= 105
s[i] is a digit or character '*' in 0 - 9

Problem solving ideas

I'm too tired to write. That's it.
It should be noted that the case of s[i]==0 is discussed, and it is easy to overflow. The remainder must be taken at each calculation step

code

class Solution {
public:
    int numDecodings(string s) {
        int n = s.length();
        unsigned long long  dp[n+1];
        dp[0]=1;
        if(s[0]=='*') dp[1]=9;
        else if(s[0]=='0') return 0;
        else dp[1]=1;
        int i;
        unsigned long long a=1E9+7;
        
        for(i=2;i<=n;i++){
            int val = (int)(s[i-1]-'0');
            if(val>=7&&val<=9){
                if(s[i-2]=='*') dp[i]=(dp[i-1]+dp[i-2])%a;
                else{
                    int preval = (int)(s[i-2]-'0');
                    if(preval ==1) dp[i]=(dp[i-1]+dp[i-2])%a;
                    else dp[i]=dp[i-1];
                }
            }

            else if(val>=1&&val<=6){
                if(s[i-2]=='*') dp[i]=(dp[i-1]+dp[i-2]*2)%a;
                else{
                    int preval = (int)(s[i-2]-'0');
                    if(preval==1||preval==2) dp[i]=(dp[i-1]+dp[i-2])%a;
                    else dp[i]=dp[i-1];
                }
            }
            else if(val==0){
                if(s[i-2]=='1'||s[i-2]=='2') dp[i]=dp[i-2];
                else if(s[i-2]=='*') dp[i]=dp[i-2]*2%a;
                else return 0;
            }
            else if(s[i-1]=='*'){
                if(s[i-2]=='*') dp[i]=dp[i-1]*9%a+dp[i-2]*15%a;
                else{
                    int preval = (int)(s[i-2]-'0');
                    if(preval==1) dp[i]=dp[i-1]*9%a+dp[i-2]*9%a;
                    else if(preval==2) dp[i]=dp[i-1]*9%a+dp[i-2]*6%a;
                    else dp[i]=dp[i-1]*9%a;
                }
            }
        }

        
        return dp[n]%a;
    }
};

Topics: C++ leetcode