91. 解码方法

一条包含字母 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


思路:

第一个元素如果是1,那么就一种可能

如果加进来了一个2,那么两种 1 - 2或者12

如果再加进来一个2,那么三种1 - 2 - 2 或者12 - 2或者一个新的1 - 22

如果再加进来一个2,那么五种1 - 2 - 2 - 2或者12 - 2 - 2或者1 - 22 -2 或者两个新的1 - 2 - 22和12 - 22

现在就可以看出来了,是一个DP的算法题,加进来的数可能是可以直接贴上去的,可能是要单独的,也可能是没有用的

看到评论里有个说,想个逻辑5分钟,划分边界2小时,评论夸张了点,但是也到位

这题如果没有边界的话,其实就是一个很简单的DP问题

class Solution {
    public int numDecodings(String s) {
        char[] arr = s.toCharArray();
        int[] dp = new int[s.length()+1];
        dp[0] = 1;
        dp[1] = arr[0]=='0'?0:1;
        if(s.length()<=1) return dp[1];
        for(int i=2;i<=s.length();i++){
            int n = (arr[i-2]-'0')*10+(arr[i-1]-'0');
            //如果最后一位=='0',且新加入的=='0',无法解码,返回0;
            if(arr[i-1]=='0' && arr[i-2]=='0'){
                return 0;
            }
            //如果只有最后一位=='0',则新加入的只能单独放在最后,不能与最后一位合并(不能以0开头)
            else if(arr[i-2]=='0'){
                dp[i] = dp[i-1];
            }
            //如果只有新加入的=='0',则新加入的不能单独放置,必须与最后一位合并,并且如果合并结果大于26,返回0,否则
            else if(arr[i-1]=='0'){
                if(n>26) return 0;
                dp[i] = dp[i-2];
            }
            //如果 合并<=26: 则新加入可以“单独”放在每个解码结果之后后,并且如果以最后一位单独结尾,此时可以合并
            else if(n>26){
                dp[i] = dp[i-1];
            }
            //如果 合并>26: 此时最后一位又不能与新加入的合并,新加入的只能单独放在dp[i]的每一种情况的最后
            else{
                dp[i] = dp[i-1]+dp[i-2];
            }
        }
        return dp[dp.length-1];
    }
}
原文地址:https://www.cnblogs.com/zzxisgod/p/13414476.html