LeetCode 91. 解码方法(java代码和思路分析)

题目传送门

解题思路:

动态规划问题(dp)。
一个字母对应了唯一的编码,所以正着编码一定是唯一的。
但是反过来就不唯一了。
我们要找一共有多少种方法反编码


dp分析:
考虑集合的表示:
f[i]一维集合,代表着前i个数字一共有多少种反编码方式

考虑状态的计算:
编码数字一共只有1到26,所以编码只有一位和两位。

  1. 如果是一位的话,数字介于1~9之间。没有0!!
  2. 如果是两位的话,数字介于10~26之间

从前遍历,当前第i位。
这样我们就可以分出两种情况:

  1. 如果当前位s[i](字符串的第i个,字符串用s表示)大于0且小于10,那么当前为可以单独表示一个字母的编码。前i位的编码方式要加上f[i-1]。(当前位唯一确定,组成方式就是前i-1个的组成方式)。
  2. 计算出s[i - 1] * 10 + s[i]的数值,即当前位和前一位表示的数字。如果在10~26之间,代表这两个数字也可以反编码出来。前i位的编码方式加上f[i-2]。(s[i-1]和s[i]唯一确定了,组成方式是前i-2个的组成方式)

代码实现:

class Solution {
    public int numDecodings(String s) {
        int len = s.length();
        s = " " + s;

        int[] f = new int[len + 10];
        // 没有数字对应空字符串,为1
        f[0] = 1;

        for (int i = 1; i <= len; i ++ ) {
            if(s.charAt(i) >= '1' && s.charAt(i) <= '9') f[i] += f[i - 1];
            int t = (int)(s.charAt(i - 1) - '0') * 10 + (int)(s.charAt(i) - '0');
            if(t >= 10 && t <= 26) f[i] += f[i - 2];
        }
        return f[len];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值