Leetcode: Decode ways

A message containing letters from A-Z is being encoded to numbers using the following mapping:

'A' -> 1
'B' -> 2
...
'Z' -> 26

Given an encoded message containing digits, determine the total number of ways to decode it.

For example,
Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12).

The number of ways decoding "12" is 2.

思路:

采用动态规划来解决,假设知道对于字符串s,从位置0解析到n-1和n-2时的解法数d[n-1]和d[n-2],那对于第n个字符就会有以下几种情况:

1.s[n]为0,且它与s[n-1]的组合是违法的,那s[n] = 0;

2.s[n]为0,但它与s[n-1]是合法组合,那s[n] = s[n-2];

3.s[n]不为0,且它与s[n-1]是合法组合,那s[n] = s[n-1] + s[n-2];

4.s[n]不为0,但它与s[n-1]的组合是违法的,那s[n] = s[n-1]


具体代码实现如下:

<pre name="code" class="cpp">class Solution {
public:
    static int numDecodings(string s) {
        if (s.empty()  || s[0] == '0')
            return 0;
        if (s.size() == 1)
            return 1;

        //第一个字符肯定是合法的数字,只有一种解法
        int preSecond = 1;
        int preOne = 0;
        if (canCompose(s[0], s[1]) && s[1] != '0')
            preOne = 2;
        else if ((canCompose(s[0], s[1]) && s[1] == '0')  //第二个字符为0,只能与第一个字符组合
            || (!canCompose(s[0], s[1]) && s[1] != '0')   //第二个字符不为0,但不能与第一个字符组合,只能分开解析
            )
            preOne = 1;
        else  //无论如何前两个字符都无解
            return 0;

        for (int i = 2; i < s.size(); ++i)
        {
            if (s[i] == '0')
            {   
                if (canCompose(s[i - 1], s[i]))
                    //情况1
                    std::swap(preOne, preSecond);
                else
                    //情况2
                    return 0;
            }                     
            else if (canCompose(s[i - 1], s[i]))
            {
                //情况3
                preOne += preSecond;
                preSecond = preOne - preSecond;
            }
            else
                //情况4
                preSecond = preOne;
        }

        return preOne;
    }

private:
   

    static bool canCompose(char chPre, char chPost)
    {
        if (chPre == 0)
            return false;
        if (chPre == '1' || (chPre == '2' && chPost <= '6'))
            return true;
        return false;
    }
};


 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值