LeetCode OJ 之 Decode Ways (解码方式)

这篇博客讨论了LeetCode中的解码问题,如何将数字编码的字符串解码为字母。作者介绍了问题背景,提供了两种解码方法,并分享了详细的解题思路。文章通过分析从i-1到i+1及从i到i+1的条件,建立了动态规划的解决方案,以计算解码的总方法数。最后,博客给出了两段代码实现。
摘要由CSDN通过智能技术生成

题目:

Amessage containing letters from A-Z is being encoded to numbers usingthe following mapping:

一条信息包含从A-Z的字母,但是这些字母使用下面的映射编码成了一串数字。

'A' -> 1

'B' -> 2

...

'Z' -> 26

Givenan encoded message containing digits, determine the total number of ways todecode it.

给定由数字组成的一串编码过的信息,确定这串数字可以有多少种解码方法。

Forexample,
Given encoded message "12", it could be decoded as "AB" (12) or "L" (12).

Thenumber of ways decoding "12" is 2.12可能解码AB,也可能解码L,所以有2解码方法)。

思路:

可以先参考爬楼梯问题:http://blog.csdn.net/u012243115/article/details/41089613

但是这一题还要具体分析一些情况,因为从i-1i+1以及从ii+1是有条件的。

dp[i+1]表示前i+1个字符(即s[0]s[i])可以编码的数量
dp[i+1] = dp[i] + dp[i-1]

下面分析可以从i-1i+1以及从ii+1的条件
可以从ii+1的条件:只要当前字符s[i] != ‘0’ ,s[i] = "1,2,3,4,5,6,7,8,9",那么dp[i]就可以和当前字符组到一起,即"dp[i],s[i]"
可以从i-1i+1的条件:前一个字符s[i-1]和当前字符s[i]要组在一起,即符合10<="s[i-1]s[i]" <= 26 即可,其他情况,s[i-1]s[i]都不能放在一起

代码1:

class Solution {
public:
    int numDecodings(string s) 
      {
        int n = s.size();
        if( n<=0 || s[0]=='0') 
            return 0;
        vector<int> dp(n+1, 0);
        dp[1] = dp[0] = 1;
        for(int i=2; i<=n; ++i)
        {
            if(s[i-1] != '0') 
               dp[i] = dp[i-1];
            if(s[i-2]=='1' || (s[i-2]=='2'&&s[i-1]<'7'))
              dp[i] += dp[i-2];
        }      
        return dp[n];
    }
};


 

代码2:

class Solution {
public:
    //优化了空间复杂度,用几个动态变量保存当前i个字符的编码数量
    int numDecodings(string s) 
	{
	    if(s.empty() || s[0] == '0')
	        return 0;
        int pre_2 = 1;
        int pre_1 = 1;
        int cur = 0;
        //注意遍历的当前字符是i-1,所以i可以取到s.size()
        for(int i = 2 ; i <= s.size() ; i++)
        {
            if(s[i-1] != '0')
                cur += pre_1;
            if(s[i-2] == '1' || (s[i-2] == '2' && s[i-1] <'7'))
                cur += pre_2;
            pre_2 = pre_1;
            pre_1 = cur;
            cur = 0;
        }
        return pre_1;//循环结束时pre_1保存的才是解码数量,而cur为0
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值