LeetCode-91. 解码方法

目录

    • 动态规划

题目来源
91. 解码方法

动态规划

  • 1.确定dp数组以及下标的含义

dp[i]表示前i个数字一共有多少种解码方式,那么,dp[n]就表示前n个数字一共有多少种不同的解码方式

  • 2.确定递推公式

对于字符串 s 的任意位置 i 而言,其存在三种情况:
只能由位置 i 的单独作为一个item,设为 a,转移的前提是 a 的数值范围为 [1,9],转移逻辑为 dp[i]=dp[i−1]。
只能由位置 i 的与前一位置(i-1)共同作为一个 item,设为 b,转移的前提是 b 的数值范围为 [10,26],转移逻辑为 dp[i]=dp[i−2]。
位置 i 既能作为独立 item 也能与上一位置形成 item,转移逻辑为 dp[i]=dp[i−1]+dp[i−2]。

dp[i]=dp[i−1],1⩽a≤9
dp[i]=dp[i−2],10⩽b⩽26
dp[i]=dp[i−1]+dp[i−2],1⩽a≤9,10⩽b⩽26
  • 3.dp数组如何初始化

dp[0] = 1,解码前0个数的方案数为1。
dp[0]代表前0个数字的方案数,这样的状态定义其实是没有实际意义的,但是dp[0]的值需要保证边界是对的,即dp[1]和dp[2]是对的。比如说,第一个数不为0,那么解码前1个数只有一种方法,将其单独解码,即dp[1] = dp[1 - 1] = 1。解码前两个数,如果第1个数和第2个数可以组合起来解码,那么dp[2] = dp[1] + dp[0] = 2,否则只能单独解码第2个数,即f[2] = f[1] = 1。因此,在任何情况下f[0]取1都可以保证f[1]和f[2]是正确的,所以f[0]应该取1。

  • 4.确定遍历顺序

从递归公式dp[i]=dp[i−1]+dp[i−2]中可以看出,遍历的顺序一定是从左到右遍历

  • 5.举例推导dp数组

以s = "226"例

LeetCode-91. 解码方法_第1张图片

代码实现

class Solution {
    public int numDecodings(String s) {
        int n = s.length();
        int[] dp = new int[n+1];
        dp[0] = 1;  //如果只有一个数 2的时候,那么dp[i] = dp[i-1] 就为1
        for(int i = 1;i<dp.length;i++){
            int a = s.charAt(i-1)-'0';
            if(a>=1 && a<=9){
                dp[i] = dp[i-1];   //单独解码s[i - 1]
            }
            if(i>=2){
                int b = (s.charAt(i-2)-'0')*10+s.charAt(i-1)-'0';
                if(b>=10 && b<=26){
                    dp[i] += dp[i-2];   //将s[i - 2] 和 s[i - 1]组合解码
                }
            }
        }
        return dp[dp.length-1];
    }
}

LeetCode-91. 解码方法_第2张图片

你可能感兴趣的:(西南科技大学算法,leetcode,算法,职场和发展)