【动态规划打怪升级】——解码方法

简介: 【动态规划打怪升级】——解码方法

一、动态规划练级攻略

  • 1.状态表示(确定dp数组的含义)
  • 2.状态转移方程(确定递推公式)
  • 3.初始化
  • 4.遍历顺序
  • 5.返回值

二、解码方法

解码方法

思路:动态规划

  • 1.确定状态表示(dp[i]的含义)
    dp[i]:以第i个位置为结尾的解码方法有dp[i]种。
  • 2.确定状态转移方程(dp[i]等于什么)
    我们分析一下:

由状态表示,解码方式可分为:

  1. s[i]单独解码
  2. s[i] 和s[i-1]一起解码

如果是第一种情况,则s[i]有2种情况:

s[i]解码成功和s[i]解码失败。

(1)

如果s[i]解码失败,那么不管s[i]之前的解码是否成功,都全盘清空。所以当s[i]解码失败是,有0种方法。

(2)

如果s[i]解码成功,则dp[i] = dp[i-1]

因为如果s[i]解码成功,说明它之前的所有字符一定解码成功,则方法数就是dp[i-1]的方法数。这个类似于爬楼梯的问题,爬到第i层楼梯只有两种情况,第i-1层楼梯往上迈一步,或者第i-2层楼梯往上迈两步。方法数都是dp[i-1]或dp[i-2]。

那么解码成功的前提条件是:9 >= a >=1

以上是s[i]单独解码的情况。

以下是s[i]和s[i-1]一起解码的情况。

(1)如果s[i]和s[i-1]一起解码失败,那么即使s[i-1]之前都解码成功,总的解码方法数都是0。

(2)如果s[i]和s[i-1]一起解码成功,那么dp[i] = dp[i-2]。

那么解码成功的前提条件是:

10<= b*10 + a <= 26,b是十位上的数,所以需要乘10

注意这里是大于等于10,而不是大于等于1。

因为如果是大于等于1,会出现下面的情况:

注意题目要求,以0为前导的字符串是不能单独解码的。

所以状态转移方程为:

dp[i] = dp[i-1] + dp[i-2]

还有一个需要注意的点:

这里为什么是s[i]和s[i-1]共同解码,而不是s[i]和s[i+1]呢?

我们需要注意到,dp[i]的含义是:以i位置为结尾的解码方法数为dp[i],当我们计算到s[i]位置时,后面的位置还没有考虑到,所以是s[i]与s[i-1]解码而不是s[i]与s[i+1]解码。

  • 3.如何初始化
    由状态转移方程:dp[i] = dp[i-1] + dp[i-2]. 我们应该初始化dp[0]和dp[1].
    s[0]单独解码时,有成功和失败两种情况,所以dp[0] = 0/1;
    代码如下:
dp[0] = s[0] != '0'

s[0]和s[1]共同解码时,有以下情况:

(1)解码失败,也就是s[0]为前导0。dp[1] = 0

(2)s[0]!=‘\0’,此时会成功解码一次,dp[1] +=1

(3)10<= b*10 + a <= 26,说明此时可以共同解码,dp[1] +=1,此时dp[1] = 2;

代码如下:

//s[1] 和 s[0]一起解码的情况
if(s[0] !='0' && s[1]!='0')
     dp[1] +=1;//只要s[0]不是0,就可以解码一次
int t = (s[0] -'0')*10 + s[1] - '0' ; 
if(t >= 10 && t <= 26)//同时可以解码
     dp[1] +=1;
  • 4.遍历顺序
    由状态转移方程可知,遍历顺序从左到右,且应该从i = 2位置开始遍历。
  • 5.返回值
    返回dp[ n-1 ]即可。

具体代码如下:

class Solution {
public:
    int numDecodings(string s) 
    {
        //1.确定dp数组的含义
        //2.确定递推公式
        //3.如何初始化
        //初始化dp[0] = 0/1 和dp[1] = 0/1/2
        //4.如何进行遍历
        //5.返回值
        //字符串解码有两种情况1:s[i]单独解码,成功的话,dp[i] = dp[i-1];
        //2.s[i] 和 s[i-1]一起解码,如果((s[i-1]-'0')*10 + s[i]-'0') >=10 && ..<=26,解码成功,dp[i] = dp[i-2];
        //所以dp[i] = dp[i-1] + dp[i-2];
        int n = s.size();
        vector<int> dp(n);
        dp[0] = s[0] !='0';//单独解码的情况
        //s[1] 和 s[0]一起解码的情况
        if(s[0] !='0' && s[1]!='0')
            dp[1] +=1;//只要s[0]不是0,就可以解码一次
        int t = (s[0] -'0')*10 + s[1] - '0' ; 
        if(t >= 10 && t <= 26)//同时可以解码
            dp[1] +=1;            
        for(int i = 2;i<n;i++)
        {
            if(s[i] != '0')//单独解码,成功
                dp[i] += dp[i-1];
            int t = (s[i-1] -'0')*10 + s[i] - '0';
            if(t >= 10 && t <= 26)//第二种情况,解码成功
                dp[i] += dp[i-2];
        }
        return dp[n-1];
    }
};

时间复杂度O(n),空间复杂度O(n)

总结

今天写了一道题解码方法的题目,比较难,但是也留下了印象。

相关文章
|
6月前
|
Python 开发工具
2024年Python最全使用Python实现音频双通道分离,2024年最新阿里p7面试难度
2024年Python最全使用Python实现音频双通道分离,2024年最新阿里p7面试难度
2024年Python最全使用Python实现音频双通道分离,2024年最新阿里p7面试难度
|
6月前
|
算法 机器人 Python
动态规划法在扫地机器人中的实战应用(基于动作值函数的策略迭代 python 附源码)
动态规划法在扫地机器人中的实战应用(基于动作值函数的策略迭代 python 附源码)
82 0
|
6月前
|
存储 算法 容器
算法刷题小技巧【持续补充~】
算法刷题小技巧【持续补充~】
28 2
|
6月前
|
搜索推荐 Java Shell
8大Java排序方法(由简入繁),有代码详解和原理指导
8大Java排序方法(由简入繁),有代码详解和原理指导
57 0
KMP算法细节详解(带动图理解)(2)
KMP算法细节详解(带动图理解)(2)
【数字IC手撕代码】Verilog自动售卖饮料机|题目|原理|设计|仿真
【数字IC手撕代码】Verilog自动售卖饮料机|题目|原理|设计|仿真
【数字IC手撕代码】Verilog自动售卖饮料机|题目|原理|设计|仿真
KMP算法细节详解(带动图理解)(1)
前言 KMP算法是为了字符串匹配问题而被研究出来的,字符串匹配问题就是查看一个字符串A是否是字符串B的子串,如果是字串的话,在B的哪个位置?此算法代码简练,但理解起来非常困难,建议挑出一整块时间来专门学习,本文作者写的非常用心,还不了解KMP的小伙伴一定要静下心来慢慢细品,你一定会有所收获🍊 一、字符串匹配问题 如果遇到这种在一个字符串中寻找另一个字符串的子串这种问题,大多数人第一时间想到的肯定是通过暴力匹配算法来完成,也就是Brute-Force算法简称BF算法,时间复杂度为O(m*n),如果有上千行上万文本呢?,时间成本一定会很高,所以D.E.Knuth,J.H.Morris和V.R.
|
存储 算法 程序员
人理解迭代,神则体会递归,从电影艺术到Python代码实现神的逆向思维模式
“从来如此,便对么?”,鲁迅先生在《狂人日记》中借狂人之口在月光下发出的质疑与呐喊,是的,从来如此,一般人的思维模式就是从来如此,以高数为例子,我们大抵都是先从数分、线代、解几去学泛函、抽代、拓扑等,其实就是按照标准路子来,这样做理论上可以增加对已学知识的理解程度,并对某些数分、线代中的问题看清其本质有所帮助。数学归纳法其实就是一种迭代(iteration),从一个简单的起点,推广到一般情况。而递归(recursion),则是一种反人类的逆向思维模式,作为研发人员,掌握这种反常识的思维逻辑是非常必要的,这里我们以一个推理故事为开端
人理解迭代,神则体会递归,从电影艺术到Python代码实现神的逆向思维模式
|
运维 监控 数据可视化
【高效编码】简单全面JDK的监控命令,看这一篇就够了!!日拱一卒
您好,我是码农飞哥,感谢您阅读本文!如果此文对您有所帮助,请毫不犹豫的一键三连吧。小伙伴们有啥想看的,想问的,欢迎积极留言告诉我喔。 上一篇文章我们介绍了JDK中一些基础的常用的命令,BUT,这还远远不够!!SO,这篇文章我们将继续来介绍JDK中监控相关的命令。话不多说,让我们直接进入主题。
655 0
【高效编码】简单全面JDK的监控命令,看这一篇就够了!!日拱一卒