Decode Ways II

来源:互联网 发布:mac os 10.13iso镜像 编辑:程序博客网 时间:2024/06/10 01:14

Decode Ways II

A.题意

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

这道题其实是另一道题目decode ways的升级版本吧,这里加多了星号表示1-9,然后要我们求出编码种类,题意大致如下

  • 1到26表示A-Z
  • 星号代表1-9任意数字
  • 输入一串带星号和数字的字符串按照上面两条规则编码返回可编码的种类

B.思路

对于这道题,我们发现编码的种类是随着字符串的增长改变的,我们用一个一维数组dp[i](这里dp[0]用于初始化了)来记录到s[i - 1]时可编码的数量,这样就分为以下三种情况

  • s[i - 1]为0
    这种情况下由于0只能与前面的1或2结合才能编码,所以根据情况,若s[i - 2]为1或2则dp[i] = dp[i - 2];
    若s[i - 2]为星号则星号表示1和2时满足编码条件则可知dp[i]为dp[i - 2]的两倍
    若不是上面两种情况则不可编码返回0

  • s[i - 1]为星号
    对于这种情况星号首先单独表示一个字符则有9种可能,首先我们给dp[i]加上9*dp[i - 1],
    接下来我们分析一下星号与前面的字符结合表示一个字符的编码个数,
    若前一个字符即s[i - 2]为1时,星号表示的9个数字均可以与1结合表示一种编码故可为dp[i]加上9 * dp[i - 2],
    若前一个字符即s[i - 2]为2时,星号只有表示1-6这6个数字时才能与2结合表示一种编码故为dp[i]加上6 * dp[i - 2],
    若前一个字符即s[i - 2]为号的时候则只有上述两种情况的全部能满足条件故为dp[i]加上15 dp[i - 2],

  • s[i - 1]为1到9其中一个字符
    这种情况下该字符可单独表示一个编码,所以先给dp[i]加上dp[i - 1],接下来同样地分析与前一个字符的结合情况,
    若s[i - 2]为1则任何s[i - 1]均能与其结合表示一种编码故再加上dp[i - 2],
    若s[i - 2]为2则只有s[i - 1]为1到6之间能满足编码条件,此时若s[i - 1]为1到6加上dp[i - 2]
    若s[i - 2]为星号,若s[i - 1]为1到6则星号表示1和2时能与其结合,此时加上2 * dp[i - 2],而若s[i - 1]为7到9则只有星号表示1能编码此时加上dp[i - 2]

C.代码实现

class Solution {public:    int numDecodings(string s) {        int M = 1e9 + 7;        vector<long> dp(s.size() + 1,0);        dp[0] = 1;        if (s[0] == '0')        {            return 0;        }        if (s[0] == '*')        {            dp[1] = 9;        } else {            dp[1] = 1;        }        for (int i = 2;i <= s.size();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] == '*')            {                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];                }            }            else if (s[i - 1] >= '1' && s[i - 1] <= '9') {                dp[i] += dp[i - 1];                if (s[i - 2] == '1')                {                    dp[i] += dp[i - 2];                } else if (s[i - 2] == '2' && s[i - 1] <= '6') {                    dp[i] += dp[i - 2];                } else if (s[i - 2] == '*') {                    dp[i] += (s[i - 1] >= '1' && s[i - 1] <= '6') ? (2 * dp[i - 2]) : dp[i - 2];                 }            }            dp[i] %= M;        }        return dp[s.size()];    }};
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 地球半径多少公里 原子半径大小比较 消防车转弯半径 汽车转弯半径图解 幂级数收敛半径 离子半径大小比较 曲率半径计算公式 曲率半径是什么 地球的平均半径 原子半径大小 焦半径公式推导 抛物线焦半径 收敛半径怎么求 5g基站覆盖半径 级数收敛半径 已知圆的半径求周长 离子半径变化规律 知道半径怎么算周长 圆弧半径计算公式 椭圆的焦半径公式 半径的平方怎么算 椭圆的焦半径推导 弯曲半径怎么计算 回转半径计算公式 双曲线焦半径公式 圆锥底面半径公式 抛物线焦半径公式 求圆的半径公式 圆锥曲线焦半径公式 圆锥的底面半径公式 轮胎半径计算公式 圆形周长求半径 圆管的水力半径 低压配电半径 知道弧长求半径 半径是什么意思 截面回转半径计算公式 圆的半径符号 曲率半径怎么算 地球曲率半径 半径计算公式