• 639. Decode Ways II


    问题描述:

    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:

    1. The length of the input string will fit in range [1, 105].
    2. The input string will only contain the character '*' and digits '0' - '9'.

    解题思路:

    首先,单个数字和两个数字都有可能有对应的字母,单个数字为1-9,两个数字为10-26.

    所以假设我们要求前n个数字的可能的结果:那么只与n-1和n-1个数字的可能性有关。(用prev1,prev2来表示)

    这里有一个特殊情况:0。

      1. 当0出现首位的时候,没有对应的排列,返回0

      2. 当0出现在中间的时候(即s[n] == '0'),只有在s[n-1]为‘1’,‘2’, ‘*’时有效。

    对于其他情况,即不为0的情况:

    又分为两种情况:(cur 代表 当前可能的解码个数)

      1.为数字: 1-9:一个数字只能有一个对应的字母 cur = 1

      2.为‘*’:有9个对应的字母 cur = 9

    需要对前一个数字进行分类讨论:

    1.  s[n-1] == '0' :此时只与prev2和s[n]有关: cur = cur * prev2

    2. s[n-1] == '1': 此时若后面为任意数字,都可以与1构成一个有效的解码方式; 若为*:则有9种

             cur = prev1 * cur + prev2 * cur; 

    3. s[n-1] == '2' 此时后面只有在 < '7'的情况下能构成有效解码 

             cur = prev1 * (cur == 9 ? 6 : (s[i] > '6' ? 0 : 1)) + prev2 * cur;

    4. s[n-1] == '*' *可以代替前面1-9的数字,所以对任意数字‘*’ 作为‘1’时一定成立,‘*’作为‘2’时有限制

              cur = prev1 * (cur == 9 ? 15 : (s[i] > '6' ? 1 : 2)) + prev2 * cur;

    记得更新prev1,prev2

    需要注意的是:

    对每一次的结果(即)prev2都要取模,否则有溢出的危险

    代码:

    class Solution {
    public:
        int numDecodings(string s) {
            long long prev1 = 1;
            long long prev2 = 1;
            long long m = 1e9 + 7;
            if(!s.empty() && s[0] == '0') return 0;
            for(int i = 0; i < s.size(); i++){
                long long cur = s[i] == '*' ? 9 : 1;
                if(i > 0){
                    if(s[i] == '0'){
                        if(s[i-1] == '0' || s[i-1] > '2') return 0;
                        int temp = prev1;
                        prev1 = prev2;
                        prev2 = s[i-1] == '*' ? temp*2 : temp;
                        continue;
                    }
                    if(s[i-1] == '0'){
                        cur = prev2*cur;
                    }else if(s[i-1] == '1'){
                        cur = prev1 * cur + prev2 * cur; 
                    }else if(s[i-1] == '2'){
                        cur = prev1 * (cur == 9 ? 6 : (s[i] > '6' ? 0 : 1)) + prev2 * cur;
                    }else if(s[i-1] == '*'){
                        cur = prev1 * (cur == 9 ? 15 : (s[i] > '6' ? 1 : 2)) + prev2 * cur;
                    }else{
                        cur *= prev2;
                    }
                }
                prev1 = prev2;
                prev2 = cur % m;
            }
            
            return (int)prev2;
        }
    };
  • 相关阅读:
    Orchard Oracle 支持
    讽刺的是,我在linux下使用最多的命令,竟然是windows的
    学习bash
    提高分布式环境中程序启动性能的一个方法
    MQTT X v1.4.1 正式发布
    社区力量|因为 EMQ,他上了微博热搜
    不止是现在,更关注未来:EMQ 携手高校加强物联网人才培养
    EMQ 助力西安增材制造国家研究院打造增材智能车间平台
    Kuiper 1.0.1 正式发布
    MQTT X v1.4.0 正式发布
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/9303743.html
Copyright © 2020-2023  润新知