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

解码方法

程序员文章站 2022-07-05 14:00:21
...

题目链接:

涉及知识:动态规划、分类讨论

分析:

首先从简单的情形进行分析,找出大概的状态转移方程,在逐步进行分类讨论。

假设给一个数串,". . . . . . 1258654326014 . . . . . .",dp[k] 表示 k 位数字的解码方法的总数,由于数字 1 - 26 分别表示字母 A - Z,数字为个位数或者两位数。则有两种情况:

  • 第 k 位一位数字表示一个字母:方案数为dp[k - 1],
  • 第(k - 1)和第 k 位两位数字表示一个字母:方案数为dp[k - 2]

因此,状态转移方程的一般形式为:dp[k] = dp[k - 1] + dp[k - 2]

但是,由于两种情况不一定可以同时取到,因此需要进行分类讨论。

  • 当第 k - 1 位不为 0 的时候:
    • 如果第 k 位不为 0,则第 k 位可以通过一位数字表示一个字母。
    • 当两位数字组合起来大于等于 10 小于等于 26 的时候,则可以通过两位数字的组合来表示一个字母。
  • 当第 k - 1 位为 0 的时候:
    • 如果第 k 位不为 0,则第 k 位可以通过一位数字表示一个字母。
  • 否则,存在连续两位同时为零,方案数为 0,直接返回 0

代码:

/*
 * @lc app=leetcode.cn id=91 lang=java
 *
 * [91] 解码方法
 */
class Solution {
    public int numDecodings(String s) {
        int[] dp = new int[s.length() + 5];
        dp[0] = 1; 
        dp[1] = 1;

        //特殊判断,首位为 0,无解
        if(s.length() == 0 || s.charAt(0) == '0'){
            return 0;
        }

        int i = 0;
        int tmp1 = 0;
        int tmp2 = 0;
        for(int j = 1; j < s.length(); ++j){
            i = j + 1;
            dp[i] = 0;

            //j - 1 位不为 0
            if(s.charAt(j - 1) != '0'){
                //j - 1 位为 0,j 位不为 0
                if(s.charAt(j) != '0'){
                    dp[i] += dp[i - 1];
                }

                tmp1 = s.charAt(j - 1) - '0';
                tmp2 = s.charAt(j) - '0';
                if((tmp1 == 1 || tmp1 == 2) && tmp1 * 10 + tmp2 <= 26 && tmp1 * 10 + tmp2 >= 10){
                    dp[i] += dp[i - 2];
                }
            } else if(s.charAt(j) != '0'){   //j - 1 位为 0,j 位不为 0
                dp[i] += dp[i - 1];
            } else {               //连续两个 0
                return 0;
            }
        }

        return dp[s.length()];
    }
}

上一篇: es入门2

下一篇: ES6入门