欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Leetcode 91:解码方法 Java实现

程序员文章站 2022-07-05 14:48:27
...

题目描述:
一条包含字母 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) 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/decode-ways
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:动态规划
这道题的动态规划方程不难得出,假设 dp[i-1] 是表示到 i-1 的字符串的解码方法有多少种,那么在最后面加多一个字符进去,也就是 dp[i] 的时候:
 ①假设最后一个字符单独解码,那么 dp[i] = dp[i-1]
 ②假设最后一个字符与前一个字符一起解码,那么 dp[i] = dp[i-2],但是与前一个字符一起解码的时候必须是大于等于10小于等于26的。

然而这道题难的地方在于字符串中出现了 ‘0’ 要怎么处理?

首先如果‘0’出现在字符串起始位置,那么这个字符串是无法解码的,即解码方法为 0;
其次出现在其他位置,那么就不能单独解码,只能与前一个字符一起解码,与前一个字符一起解码时,必须要大于等于10小于等于26。

所以动态规划方程是:
边界情况:
 ① 当 s[0] = ‘0’ ,字符串无法解码,返回0;当 s[0] != ‘0’,dp[0] = 1
 ② 当 s[1] != ‘0’,dp[1]=dp[0] ;当 Int(s[0],s[1]) >= 10 && Int(s[0],s[1]) <= 26, dp[1]=dp[0]+1;
注:Int(s[i-1],s[i]) 表示将 s[i-1]和s[i]两个字符转为相对应的数字,比如:Int(1,2) = 12;

非边界情况:当 s[i] != ‘0’ 时,dp[i] = dp[i-1];在前一个条件执行后,当 Int(s[i-1],s[i]) >= 10 && Int(s[i-1],s[i]) <= 26,dp[i] += dp[i-2];

(可能说的有点乱。。结合代码看的话应该就可以看懂)

public int numDecodings(String s) {
        
        //其实位置为0则无法解码
        if (s.charAt(0) == '0') {
            return 0;
        }

        //长度为1并且这个字符不为0的情况下,解码方法就只有1种
        if (s.length() == 1) {
            return 1;
        }

        int n = s.length();
        char[] chars = s.toCharArray();
        int[] dp = new int[n];
        
        // 边界情况,dp[0]=1 (s[0] != '0')
        dp[0] = 1;

        // 边界情况,dp[1] = dp[0] 还是 dp[1] = dp[0] + 1
        int num = 10 * (chars[0]-'0') + (chars[1]-'0');
        if (chars[1] != '0') {
            dp[1] = dp[0];
        }
        if (num >= 10 && num <= 26) {
            dp[1]++;
        }

        // dp[i] = dp[i-1] 或 dp[i] = dp[i-1] + dp[i-2]
        for (int i = 2; i < n; i++) {
            if (chars[i] != '0') {
                dp[i] = dp[i-1];
            }

            num = 10 * (chars[i-1]-'0') + (chars[i]-'0');
            if (num >= 10 && num <= 26) {
                dp[i] += dp[i-2];
            }
        }

        return dp[n-1];
    }

虽然这次题解写的不太好,但是还是求给一颗GitHub的start~
https://github.com/zzdreamz/Leetcode-practice