力扣动态规划第91题

https://leetcode.cn/problems/decode-ways/description/

那么我们可以设置一个数组来存储前n个数的编码的总方法数

int dp[] = new int[s.length()];

我们每次插入数的时候有多种可能

  1. 当这个数为0时判断上一个数是否能与0一起构成编码
  2. 当这个数不是0的时候,也需要判断上一个数是否能与该数一起构成编码

dp[2] = 3 dp[3] = 3 dp[4] = 6

例如前3个数为1,2,3 可分为 [1,2,3]   [12,3]   [1,23]如果第四个数为1时

我们可以看到31>26所以新加入的编码方法总数不变[1,2,3,1]   [12,3,1]   [1,23,1]

如果添加第5个数为1那么新加入的编码可以看作在[1,2,3]   [12,3]   [1,23]的基础上加了一个11  :  [1,2,3,11]   [12,3,11]   [1,23,11] 和在[1,2,3,1]   [12,3,1]   [1,23,1]的基础上加了一个1  :[1,2,3,1,1]   [12,3,1,1]   [1,23,1,1]

然后我们可以得到大致的一个规律

  1. 当这个数为0时,上一个数能与0一起构成编码

dp[ i ] = dp[ i - 2 ]

  1. 当这个数为0时,上一个数不能与0一起构成编码

return 0;

  1. 当这个数不是0的时候,上一个数能与该数一起构成编码

dp[ i ] =  dp[ i - 1 ] + dp[ i - 2 ]

  1. 当这个数不是0的时候,上一个数不能与该数一起构成编码

dp[ i ] =  dp[ i - 1 ]

然后对于一些稍微特殊情况进行判断,代码如下:

public static int numDecodings(String s) {
        int int_s[] = new int[s.length()];
        int dp[] = new int[s.length()];
        int_s[0] = (int) s.charAt(0) - 48;
        dp[0] = 1;
        if (int_s[0] == 0) {
            dp[0] = 0;
        }
        int num = dp[0];
        for (int i = 1; i < s.length(); i++) {
            int_s[i] = (int) s.charAt(i) - 48;
            if (int_s[i] == 0) {
                if (int_s[i - 1] <= 2 && int_s[i - 1] > 0) {//当这个数为0时,上一个数能与0一起构成编码
                    if (i == 1) {
                        dp[i] = 1;
                        continue;
                    }
                    dp[i] = dp[i - 2];
                    num = dp[i];
                } else {//当这个数为0时,上一个数不能与0一起构成编码
                    return 0;
                }
            } else {//这个数不是0
                if (int_s[i - 1] * 10 + int_s[i] <= 26) {//上一个数能与该数一起构成编码
                    if (i == 1) {
                        dp[i] = 2;
                        num = dp[i];
                        continue;
                    }
                    dp[i] = dp[i - 1] + dp[i - 2];
                    num = dp[i];
                } else {//上一个数不能与该数一起构成编码
                    dp[i] = dp[i - 1];
                    num = dp[i];
                }
            }
        }
        return num;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值