题目:解码方法(来自leetcode)动态规划----斐波那契模型


题目链接

题目

在这里插入图片描述

动态规划(5步走)

状态表示

dp[i]表示为从下标i之前的的解码数。

状态转移方程

以i位置为终点,下标为i的位置有两种方式:

  • 第一种就是单独解码,第二种就是与前面的一位数合并解码

  • 单独解码有分两种情况:第一种是:当s[i]在[1,9]时可以单独解码,就相当于在dp[i-1]种情况后接上一个单独解码,所以dp[i]=dp[i-1],第二种是:当s[i]=0时不可以单独解码

  • 合并解码也分两种情况:第一种:与前面的数合并后的数在[10,26]之间可以合并,就相当于把下标为i-1和i看成一个整体,放在dp[i-2]后,所以dp[i]=dp[i-2];第二种:合并后的数不在[10,26]之间,比如146和100不可以合并解码,如果第 i 位为0又不可以合并(eg.160、100),就 return 0。因为 i 位为0时说明不可以单独解码也不可以合并,所以就出现了编码错误。

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

初始化

初始化的目的是防止越界,所以要使合并时dp[i]=dp[i-2]不越界,至少i=2,所以初始化dp[0]和dp[1]。

填表顺序

从左往右,因为左边的值会对右边产生影响。

返回值

如果没有编码错误返回dp[len-1],否则返回0。

代码

int Getnum(char a,char b)
{
    int la=a-48;
    int lb=b-48;
    return la*10+lb;
}
int numDecodings(char* s) {
    
    int len=strlen(s);
    //1.创建dp表
    int dp[len];
    //2.初始化dp[0]、dp[1]
    if(s[0]=='0')
       return 0;//出现编码错误
    else
    {
        dp[0]=1;
        if(len==1)//不可少,防止dp[1]越界
        return 1;
    }
    
    if(s[1]>'0'&&s[1]<='9')
    {
        if(Getnum(s[0],s[1])<=26)
        {
            //单独解码+合并
            dp[1]=2;
        }
        else
        {
            //单独解码
            dp[1]=1;
        }
        
    }
    else
    {
        //为0,只能合并,否则return 0
        if(Getnum(s[0],s[1])<=26)
        {
            //只可以合并
            dp[1]=1;
        }
        else
        {

          return 0;
        }
    }

    //3.填表。从第3位数开始使用状态方程 i=2
    int i=2;
    while(i<len)
    {
        //单独解码+合并解码
        if(s[i]>'0'&&s[i]<='9')
        {
            //可以单独解码
            if(Getnum(s[i-1],s[i])>=10&&Getnum(s[i-1],s[i])<=26)
            {
                //单独解码+合并解码
                dp[i]=dp[i-1]+dp[i-2];
            }
            else
            {
                //单独解码
                dp[i]=dp[i-1];
            }
        }
        else
        {
            //为0,只可以合并,否则return0
            if(Getnum(s[i-1],s[i])>=10&&Getnum(s[i-1],s[i])<=26)
            {
                //合并解码
                dp[i]=dp[i-2];
            }
            else
            {
                //不可以合并解码,也不可以单独解码
                return 0;
            }
        }
      i++;
    }

    return dp[len-1];

}

有什么问题可以在评论区@我。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值