LeetCode -> 91. 解码方法

https://i-blog.csdnimg.cn/blog_migrate/8bd0239a44d2f6ead63870d5030a2877.png

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

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

给定一个只包含数字的非空字符串,请计算解码方法的总数。

示例 1:

输入: "12"
输出: 2
解释: 它可以解码为 "AB"(1 2)或者 "L"(12)。

示例 2:

输入: "226"
输出: 3
解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。

动规首先就是要分解子问题嘛

首先捏,从宏观上来看,先不管各种限制,进行如下分析:

字符串长度为1时,假设字符串是“1”,F(1)= 1;

字符串长度为2时,假设字符串是“12”,F(2)= 2;情况有:(1,2)(12)

字符串长度为3时,假设字符串是“123”,F(3)= F(2) + F(1);

为什么是这样呢?

情况一:“3” 和 “12”的情况,“12”的种类正是F(2)

情况二:“23” 与 “1”的情况,“1”的种类正是F(1)

有些人就奇怪,为什么不算”23“的种类,来看一下”23“可以分成(2,3)和(23),但是”2,3“这种情况在情况一中已有体现(情况一已把3单独拆开),情况二这里再算的话就会有重复。

以此类推,F(n) = F(n - 1) + F(n -2 );

接下来看到细节:

分析情况一:解码方法数为:最后一个数字提取出来,这个数字之前的字符串的解码方法数。

提取数字前的字符串解码方法数F(n - 1)不多bb,分析一下提取出来的数字。

根据题意可知(1~26)表示A~Z,其中单个数字范围就是1~9了

所以可知提取出来的数字是0时,情况一为0,否则才是F(n - 1);

分析情况二:解码方法数为:最后两个数字提取出来,这俩数字之前的字符串的解码方法数。

提取数字前的字符串解码方法数F(n - 2)不多bb,分析一下提取出来的俩数字。

根据题意可知(1~26)表示A~Z,其中单个数字范围就是10~27了

所以大于27或小于10情况二直接为0,否则是F(n - 2);

 

代码如下:

public int numDecodings(String s) {
        if (s == null)
            return 0;
        int[] ints = new int[s.length() + 1];
        ints[0] = 1;
        char[] cs = s.toCharArray();
        if (ints.length > 1)
            ints[1] = cs[0] == '0' ? 0 : 1;
        for (int i = 2; i < ints.length; i++){
            if (cs[i - 2] != '0' && (cs[i - 2] == '1' || cs[i - 2] == '2' && cs[i - 1] < '7'))
                ints[i] += ints[i - 2];
            if (cs[i - 1] != '0')
                ints[i] += ints[i - 1];
        }
        return ints[ints.length - 1];
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值