[leetcode] 91. Decode Ways

A message containing letters fromA-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.

这道题是破译密文获取可能的明文数,题目难度为Medium。

看到这道题通过率很低所以做了下试试,一道比较典型的动态规划题目,本身比较简单,不过测试用例略坑。用一个具体例子来说明,假如密文是123454321,可以把密文分为123454321和123454321两种情况来考虑。第一种情况我们把最后的1作为一个字母的密文,只要知道前面数字12345432可能的明文数即得到了第一种情况的明文数。同理第二种情况只要知道1234543可能的明文数即可。这样把两种情况相加就得到了最终的结果。这里有两点需要注意,第一种情况最后一位不能是0;第二种情况倒数第二位必须是1或2。

这样题目应该解决了,现在开始吐槽测试用例。好吧傲娇一下,都说密文是经过以上方法加密来的了,怎么还会有不合理的密文,例如001,100这种,估计这道题通过率这么低就是这个原因。针对这种奇葩密文,可以看出,第一个数字不能是0,同时0之前的数字只能是1或2。只能怪考虑的不够周全了。。

最终结果只依赖于它之前的两种情况,因此我们不必针对密文的每个位置记录下可能的明文数,只需要三个数字循环使用就可以了,这样可以把空间复杂度从O(n)降到O(1)。具体代码:

class Solution {
public:
    int numDecodings(string s) {
        if(s.empty() || s[0]=='0') return 0;
        int n1 = 1, n2 = 1, n3 = 0;
        for(int i=1; i<s.size(); ++i) {
            if(s[i] != '0') 
                n3 += n2;
            else if(s[i-1]!='1' && s[i-1]!='2')
                return 0;
            if((s[i-1]=='1') || (s[i-1]=='2' && s[i]<'7'))
                n3 += n1;
            n1 = n2;
            n2 = n3;
            n3 = 0;
        }
        return n2;
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值