【leetcode-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) 。

注意,输入100,输出是0.题目未说明。自己写的时候在这个地方犯错。

非常类似于斐波那契序列,可以理解为dp[i]=dp[i-1]+dp[i-2]。但是这个是有条件的:如果以i为结尾的字符串,最后两位不在10-26之间,那么dp[i-2]这一项就不能加,因为如果从i-2到i直接过度,需要一个10-26的两位数。同样的,如果最后一位为0,那么dp[i-1]这一项也不可以加,因为从i-1过渡到i需要一个1-9的数。

// dp[i]表示s[0~i-1]可以有多少种解码方式
// 递推方程:如果1 <= s[i-1] <= 9,则dp[i] += dp[i-1]; 
// 如果10 <= s[i-2 ~ i-1] <= 26, 则dp[i] += dp[i-2].
链接:https://www.nowcoder.com/questionTerminal/a2539eb0a9ec4c54a055091e706072cc
来源:牛客网

import java.util.*;
public class Solution {
    public int numDecodings(String s) {
        if (s.length() == 0 || s.charAt(0) == '0') return 0; if (s.length() == 1) return 1; int f[] = new int[s.length() + 1];
        f[0] = 1; // 当有0个字符时候的编码个数,当有连续两个字符能编码时f[i] = f[i-2],保证f[0]有值
        f[1] = 1; // 字符串长度为1时的编码个数
        for (int i = 1; i < s.length(); i++) {
            String num = s.substring(i - 1, i + 1);
            // 两个字符能否拼成一个编码
            if (Integer.valueOf(num) <= 26 && s.charAt(i - 1) != '0') {
                f[i + 1] = f[i + 1 - 2];
            } 
            // 单个字符能够构成编码,如果含0,则不能编码。
            f[i + 1] += s.charAt(i) != '0' ? f[i + 1 - 1] : 0;
        }
        return f[s.length()];
    }
}
原文地址:https://www.cnblogs.com/twoheads/p/10843995.html