【动态规划】【斐波那契数列模型】解码方法

解码方法

91. 解码方法
image.png|462
image.png|426

算法原理

  1. 确定状态表示

    • 经验+题目要求:
    • i 位置为结尾
    • dp[i] 表示以 i 位置为结尾时,解码方法的总数
  2. 状态转移方程

定义好状态表示,我们就可以分析 i 位置的 dp 值,如何由 [前面] 或者 [后面] 的信息推导出来。关于 i 位置的编码状况,我们可以分为下面两种情况:

  1. i 位置上的数单独解码成一个字母
  2. i 位置上的数与 i-1 位置上的数结合,解码成一个字母

下面我们就上面的两种解码情况,继续分析:

  • i 位置上的数单独解码成一个字母,就存在 [解码成功][解码失败] 两种情况:

    1. 解码成功:当 i 位置上的数在 [1, 9] 之间的时候,说明 i 位置上的数是可以单独解码的,那么此时 [0, i] 区间上的解码方法应该等于 [0, i-1] 区间上的解码方法。因此 [0, i-1] 区间上的所有解码结果,后面填上一个 i 位置解码后的字母就可以了。此时 dp[i] = dp[i-1]
    2. 解码失败:当 i 位置上的数是 0 的时候,说明 i 位置上的数是不能单独解码的,那么此时 [0, i] 区间上不存在解码方法。因为 i 位置如果单独参与解码,但是解码失败了,那么前面做的努力就全部白费了。此时 dp[i] = 0
  • i 位置上的数与 i-1 位置上的数结合在一起,解码成一个字母,也存在 [解码成功][解码失败] 两种情况:

    1. 解码成功:当结合的数在 [10, 26] 之间的时候,说明 [i-1, i] 两个位置是可以解码成功的,那么此时 [0, i] 区间上的解码方法应该等于 [0, i-2] 区间上的解码方法,原因同上。此时 dp[i] = dp[i-2]
    2. 解码失败:当结合的数在 [0, 9][27, 99] 之间的时候,说明两个位置结合后解码失败(这里一定要注意 00010203… 这几种情况),那么此时 [0, i] 区间上的解码方法就不存在了,原因依旧同上。此时 dp[i] = 0

综上所述:dp[i] 最终的结果应该是上面四种情况下,解码成功的来那个中的累加和(因为我们关心的是解码方法,既然解码失败,就不用加入到最终的结果中去),因此可以得到状态转移方差(dp[i] 默认初始化为 0)

  1. s[i] 上的数在 [1, 9] 区间上时:dp[i] = dp[i-1]

  2. s[i-1]s[i] 上的数结合之后,在 [10, 26] 之间的时候:dp[i] += dp[i-2]
    如果上述两个判断都不成立,说明没有解码方法,dp[i] 就是默认值 0

  3. 初始化
    由于可能要用到 i-1 以及 i-2 的位置上的 dp 值,因此要先初始化 [前两个位置]

初始化 dp[0]

  1. s[0] == ‘0’ 时,没有编码方法,结果 dp[0] = 0
  2. s[0] != '0' 时,能编码成功,dp[0] = 1

初始化 dp[1]

  1. s[1][1, 9] 之间时,能单独编码,此时 dp[1] += dp[0](原因同上,dp[1] 默认为 0)

  2. s[0]s[1] 结合后的数在 [10, 26] 之间时,说明在前两个字符中,又有一种编码方式,此时 dp[1] += 1

  3. 填表顺序

    • 毫无疑问,是从左往右
  4. 返回值

    • 应该返回 dp[n-1] 的值,表示在 [0, n-1] 区间上的

代码编写

public int numDecodings(String ss) {  
    //1. 创建 dp 表(看返回值)  
    int n = ss.length();  
    int[] dp = new int[n];  
    char[] s = ss.toCharArray();  
  
    //2. 初始化  
    //初始化 dp[0]    
    if(dp[0] != '0') dp[0] = 1;  
    if(n == 1) return 1;  
  
    //初始化 dp[1]    
    if(s[1] != '0' && s[0] != '0') dp[1] += 1;  
    int t = (s[0] - '0') * 10 + (s[1] - '0');  
    if(t >= 10 && t <= 26) dp[1] += 1;  
  
    //3. 填表  
    for (int i = 2; i < n; i++) {  
        if(s[i] != '0') dp[i] += dp[i-1];  
  
        int tt = (s[i-1] - '0') * 10 + (s[i] - '0');  
        if(tt >= 10 && tt <=26) dp[i] += dp[i-2];  
    }  
  
    return dp[n-1];  
}
  • dp 表只需要 n 位,是因为最后是返回 dp[n-1],可以到
  • s[0]-'0's[1]-'0' 可以得到对应字符的编码

优化原理

处理边界问题以及初始化问题的技巧

在 dp 表中增加一个虚拟节点,把原来初始化起来很麻烦的 s[1] 挤到第三位,而我们初始化对象只是前两位image.png|459


注意事项:

  1. 虚拟节点里面的值,要保证后面的填表是正确的

当我们计算 dp[2] = dp[1] + dp[0] 的时候,dp[1] 是不会出错的,因为原来的 dp 表中就有,但 dp[0] 是我们虚拟出来的节点,这个节点里面存多少,就很重要

一般虚拟节点都是存 0,但这里不行,得存 1

  • s[0]s[1] 结合起来能解码成功的话,按照状态表示,就要加上前面的值(新 dp[0]
  • 如果填 0 的话,这个解码方式就忽略掉了,所以不能填 0
  1. 下标的映射关系
  • s[1-1] != '0'

代码编写

public int numDecodings2(String ss) {  
    int n = ss.length();  
    int[] dp = new int[n+1];  
    char[] s = ss.toCharArray();  
  
    dp[0] = 1;  
    if(s[1-1] != '0') dp[1] = 1;  
  
    for (int i = 2; i <= n; i++) {  
        if(s[i-1] != '0') dp[i] += dp[i-1];  
  
        int tt = (s[i-2] - '0') * 10 + (s[i-1] - '0');  
        if(tt >= 10 && tt <= 26) dp[i] += dp[i-2];  
    }  
  
    return dp[n];  
}
  • 初始化 dp 表的时候需要多一位,n+1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/894706.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode 1137. 第 N 个泰波那契数

原题链接&#xff1a;Leetcode 1137. 第 N 个泰波那契数 代码1&#xff1a; class Solution { public:int a[40];int tribonacci(int n) {a[0]0;a[1]1;a[2]1;if(n<1) return n;if(a[n]) return a[n];a[n]tribonacci(n-1)tribonacci(n-2)tribonacci(n-3);return a[n];} };代…

【LeetCode】每日一题 2024_10_19 使二进制数组全部等于 1 的最少操作次数 II(贪心)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;使二进制数组全部等于 1 的最少操作次数 II 力扣每日一题刷新规律&#xff0c;昨天刷新了 I&#xff0c;那今天必定有 II。 代码与解题思路 今天的题目和昨天的非常像&#xff0c;只有一…

SVM支持向量机python实现

支持向量机&#xff08;Support Vector Machine, SVM&#xff09;是一种强大的监督学习算法&#xff0c;主要用于分类和回归任务。SVM的核心思想是找到一个最优的超平面&#xff0c;使得不同类别的数据点能够被尽可能清晰地分开&#xff0c;并且这个超平面与最近的数据点之间有…

SpringCloud无介绍快使用,单机Eureka服务注册中心cloud-eureka-server7001搭建(十)

TOC 问题背景 从零开始学springcloud微服务项目 注意事项&#xff1a; 约定 > 配置 > 编码IDEA版本2021.1这个项目&#xff0c;我分了很多篇章&#xff0c;每篇文章一个操作步骤&#xff0c;目的是显得更简单明了controller调service&#xff0c;service调dao项目源码以及…

微软的 Drasi:一种轻量级的事件驱动编程方法

微软的开源数据变化处理平台有望提供一种全新的方式来构建和管理可产生持续事件流的云应用程序。 Microsoft Azure 孵化团队是微软超大规模云中比较有趣的组成部分之一。它介于传统软件开发团队和研究组织之间&#xff0c;致力于构建大规模分布式系统问题的解决方案。 这些解决…

Kettle9.4支持Clickhouse数据源插件开发以及性能测试

前言 最近业务这边有个指标需要用到大数据这边的列式数据库进行处理&#xff0c;由于kettle不支持clickhouse数据源驱动&#xff0c;这里查了一下网上的相关资料&#xff0c;发现了一些别人开发好的驱动包&#xff0c;下载下来后使用效果不尽人意。总结下来有以下几个问题&…

【C++】string类(接口使用详解 下)

我们接着【C】string类&#xff08;接口使用详解 上&#xff09;-CSDN博客 继续介绍string的使用。 1.string类对象的修改操作 我们就说一下用的比较多的接口。 1.1 operator 这个接口可以尾插一个字符&#xff0c;或者一个字符串&#xff0c;或者一个对象。 string s1(&qu…

回归测试内容多,时间紧,人还少,怎么办?

问答网站上看到一个提问&#xff1a; 项目进入测试&#xff0c;但回归测试内容多&#xff0c;发布时间紧迫&#xff0c;人还少&#xff0c;要怎么做&#xff1f; 标准答案应该是自动化测试 回归测试主要关注的是历史功能&#xff0c;如果自动化测试覆盖率达到一定程度的话&…

lazyLoad

//1.通过React的lazy函数配合import()函数动态加载路由组件 > 路由组件代码会被分开打包 const Login lazy(()>import(/pages/Login)) //2.通过<Suspense>指定在加载得到路由打包文件前显示一个自定义loading界面 <Suspense fallback{<h1&…

探索Spring Cloud Config:构建高可用的配置中心

目录 认识Spring Cloud ConfigConfig Server读取配置文件步骤1&#xff1a;&#xff08;1&#xff09;创建config-server项目&#xff08;2&#xff09;在config-server中开启Config Server功能&#xff08;3&#xff09;在config-server配置文件进行相关配置&#xff08;4&…

计算机毕业设计Python深度学习房价预测 房源可视化 房源爬虫 二手房可视化 二手房爬虫 递归决策树模型 机器学习 深度学习 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 房地产是促进我国经济持续增…

征程 6E DISPLAY 功能介绍及上手实践

01 功能概述 本文将带大家一起实现单路、多路 MIPI CSI TX 输出、IDU 回写、IDU oneshot 模式、绑定输出 VPS 数据等功能&#xff0c;此处主要介绍各 sample 的实现与使用方法。 02 软件架构说明 本文中绑定 VPS 输出功能基于 libvio API 实现&#xff0c;调用 libvio 提供的…

Ubuntu16.04安装openssl库

Ubuntu16.04安装openssl库 Chapter1 Ubuntu16.04安装openssl库 Chapter1 Ubuntu16.04安装openssl库 原文链接&#xff1a;https://blog.csdn.net/weixin_36584476/article/details/107321893 记录一下省得忘了 1.首先去openssl官网下载源码www.openssl.org/source/&#xff0…

西瓜书书本内容杂谈

西瓜书书本内容杂谈 把圈子变小&#xff0c;把语速放缓&#xff0c;把心放宽&#xff0c;把生活打理好 只能说快速过了一遍&#xff0c;花了一个多星期吧&#xff0c;然后后边的内容是一点也看不懂了&#xff08;能发现前面记得比较详细&#xff0c;到了后边是看不懂一点了&a…

音视频基础知识分享

音视频基础知识分享 RKMedia的各个组件及其交互 首先上图&#xff1a; 考虑到公司业务主要是相机&#xff0c;所以&#xff0c;主要去关注图像数据流&#xff0c;对于音频数据流直接忽略。 图像数据流向&#xff1a; Camera Sensor将光信号转换成电信号&#xff08;Raw数据&…

基于语音识别的停车共享小程序(lw+演示+源码+运行)

目 录 1 绪论1 1.1 课题研究背景1 1.2 研究现状1 1.3 论文结构安排1 2 系统关键技术2 2.1 微信小程序2 2.2 微信Web开发者工具2 2.3 JavaScript简介2 2.4 微信小程序API接口2 2.5 MYSQL数据库2 3 系统分析1 3.1 可行性分析1 3.1.1 技术可行性1 3.1.2 经济可行性1…

如何查看公众号真实粉丝数,2024年还有哪些粉丝百万以上的大号?

如何查看公众号真实粉丝数&#xff1f;很简单&#xff0c;写了个脚本一键获取&#xff0c;看看2024年还有哪些粉丝百万以上的大号&#xff1f; 猫笔刀这个号2018-2024年的所有历史文章&#xff0c;共1168篇&#xff0c;导出的excel文章数据包含文章日期&#xff0c;文章标题&a…

bean的实例化2024年10月17日

跟不上为基础 1.你的java学习路线 2. 3.课程 注解的装配 contoller调用service用的是注解装配

【Linux】解答:为什么创建目录文件,硬链接数是2;创建普通文件时,硬链接数是1?(超详细图文)

前言 大家好吖&#xff0c;欢迎来到 YY 滴Linux系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Lin…

我在自动化测试方面犯过的3个大错误

每个人都会犯错误&#xff0c;但不管错误看起来有多糟糕&#xff0c;你都可以恢复过来&#xff0c;更重要的是&#xff0c;从错误中学习。 在软件开发过程的任何领域&#xff0c;从编码到测试&#xff0c;我们都会时不时地犯一些错误。通常&#xff0c;这些错误都很小&#xf…