动态规划--解码方法

题目描述(题目链接

一条包含字母 A-Z 的消息通过以下映射进行了编码

‘A’ -> 1
‘B’ -> 2

‘Z’ -> 26

解码已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母,可能有多种方法。例如:

“11106” 可以映射为:
“AAJF” ,将消息分组为 (1 1 10 6)
“KJF” ,将消息分组为 (11 10 6)
注意,消息不能分组为 (1 11 06) ,因为 “06” 不能映射为 “F” ,这是由于 “6” 和 “06” 在映射中并不等价。

给你一个只含数字的 非空 字符串 s ,请计算并返回解码方法的总数 。

题目数据保证答案肯定是一个 32 位 的整数。

求解思路

动态规划思想:
存储结构: dp[i]表示到第i个字符的解码方法总数
状态转移: dp[i]从以下两种方式得到:

  1. 从i-2过来,只用考虑字符串s(i-1,i)能不能被解码,若能,dp[i] += dp[i-2]
  2. 从i-1过来,只用考虑字符串s[i]能不能被解码,若能,dp[i] += dp[i-1]

初始化:

  1. 把数组dp的所有元素初始化为0
  2. 初始化dp[0],dp[1]

边界情况检查:

  1. 数组长度为1时,不能初始化dp[1],直接返回
  2. 每一处方法数为0时,说明有不能解码的字符,直接返回

代码

class Solution {
public:
    int numDecodings(string s) {
        int len = s.size();
        int dp[len];
        for(int i=0;i<len;i++){   
            dp[i] = 0;       //都初始化为0
        }
        //初始化0
        if(s[0]>='1'&&s[0]<='9') dp[0] = 1; 
        else dp[0] = 0;
        if(len==1||dp[0]==0) return dp[0];    //边界情况,数组长度为1或第0个字符的方法数为0
        //初始化1
        if(s[1]>='1'&&s[1]<='9') dp[1] += dp[0];  
        if(s.substr(0,2)>="10"&&s.substr(0,2)<="26") dp[1]++;
        if(dp[1]==0) return 0;  //边界情况,方法数为0说明有不能解码的字符,直接返回
        for(int i=2;i<len;i++){
            if(s.substr(i-1,2)>="10"&&s.substr(i-1,2)<="26") dp[i] += dp[i-2];  //状态转移 从i-2过来
            if(s[i]>='1'&&s[i]<='9') dp[i] += dp[i-1];   //状态转移  从i-1过来
            if(dp[i]==0) return 0;    //边界情况,方法数为0说明有不能解码的字符,直接返回
        }
        return dp[len-1];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值