力扣--91解码方法 c++ 动态规划实现

解码方法

一条包含字母A-Z的消息通过以下方式进行了编码:
‘A’ -> 1
‘B’ -> 2
‘C’ -> 3

‘Z’ -> 26
给定一个只包含数字的非空字符串。请计算解码方法的总数。
示例1:
输入:“12”
输出:2
解释:它可以解码为"AB"(1 2) 或者 “L”(12)。

示例2:
输入:“226”
输出:3
解释:它可以解码为"BZ" (2 26),“VF” (22 6),或者 “BBF”(2 2 6)。

思想:dp[i]为译码方法总数;s[0]为’0’,直接返回0;dp[0]和dp[1]初始化为1;s[i]==‘0’时,如果s[i-1]==1或者2,0需要与前面的1或者2结合才能编码,则此时无新的编码方式,将dp[i+1]=dp[i-1],如果前面的值不等于1或者2,则这个0无法参与编码,直接返回0。 当s[i]不为’0’时,若 s[i-1] 为’1’,或者s[i-1]为2且s[i]小于等于6大于等于1,则dp[i+1]=dp[i]+dp[-1];否则dp[i+1]=dp[i];

代码:

int numDecodings(string s)
{
    if (s[0] == '0') return 0;
    vector<int>dp(s.size() + 1);
    dp[0] = 1;
    dp[1] = 1;
    int i = 1;
    for (i; i < s.size(); ++i)
    {
        if (s[i] == '0')
        {
            if (s[i - 1] == '1' || s[i - 1] == '2')
            {
                dp[i+1] = dp[i - 1]; //由于s[1]指第二个下标,对应为dp[2], 所以dp的下标要比s大1,故为dp[i + 1]
            }
            else return 0;
        }
        else
        {
            if (s[i-1] == '1' || (s[i-1] == '2'&& s[i] <= '6'))
            {
                dp[i + 1] = dp[i - 1] + dp[i];
            }
            else
            {
                dp[i + 1] = dp[i];
             }
        }
    }
    return dp[s.size()];
}

  可以将dp数组用变量来代替,降低空间复杂度为O(1)

int numDecodings(string s) 
{
    if (s[0] == '0') return 0;
   int pre, curr;//保存前面状态和当前状态
   pre = 1;
   curr = 1;
   int i;
   for (i = 1; i < s.size(); ++i)
   {
       int tmp = curr;
       if (s[i] == '0')
       {
           if (s[i - 1] == '1' || s[i - 1] == '2')
           {
               curr = pre;//当前状态等于上一个状态
           }
           else
           {
               return 0;//30无法转换
           }
        }
        else if (s[i - 1] == '1' || (s[i - 1] == '2'&&s[i] <= '6'))
        {
            curr = curr + pre;
        }
        pre = tmp;
    }
    return curr;
}

你可能感兴趣的:(算法题)