当前位置: 首页 > news >正文

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

在这里插入图片描述

91. 解码方法

一条包含字母 A-Z 的消息通过以下映射进行了 编码

'A' -> "1"
'B' -> "2"
...
'Z' -> "26"

解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,"11106" 可以映射为:

  • "AAJF" ,将消息分组为 (1 1 10 6)
  • "KJF" ,将消息分组为 (11 10 6)

注意,消息不能分组为 (1 11 06) ,因为 "06" 不能映射为 "F" ,这是由于 "6""06" 在映射中并不等价。

给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数

题目数据保证答案肯定是一个 32 位 的整数。

示例 1:

输入:s = "12"
输出:2
解释:它可以解码为 "AB"(1 2)或者 "L"(12)。

示例 2:

输入:s = "226"
输出:3
解释:它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。

示例 3:

输入:s = "06"
输出:0
解释:"06" 无法映射到 "F" ,因为存在前导零("6" 和 "06" 并不等价)。

提示:

  • 1 <= s.length <= 100
  • s 只包含数字,并且可能包含前导零。

解题思路

​ 下图中给出了动态规划表的状态表示,还有状态转移方程:

在这里插入图片描述

​ 值得注意的是,要具体编码的时候,s[i]s[i-1] 一起解码这种情况中 10 <= a*10 + b <= 26,其中 ab 是字符,所以 必须让它们都减去 ‘0’ 才能得到对应的数字大小,这个要注意,它们并不是个位数字本身!

​ 还有就是为什么不讨论 s[i+1]s[i] 解码的情况呢❓❓❓这是因为我们 dp[i] 表示的是从头到 i 位置处的解码方法总数,所以当然不用考虑 i 后面的字符情况!

​ 现在来讨论一下初始化的问题,因为我们是从左向右推导,并且涉及到 dp[i-2]dp[i-1],那么势必要将前两个元素进行初始化。

​ 下面还是用图片的形式来给出初始化的问题:

在这里插入图片描述

class Solution {
public:int numDecodings(string s) {// 创建dp表,dp[i]:以i结尾时的解法总数int n = s.size();vector<int> dp(n);// 初始化dp[0]和dp[1],因为状态转移方程需要借助到i-1和i-2if(s[0] != '0')dp[0] = 1;if(n == 1)return dp[0]; // 处理一下边界问题,因为题目范围从1个字符开始if(s[1] != '0' && s[0] != '0') // 单独编码的情况dp[1]++;int tmp = s[1]-'0' + (s[0]-'0')*10; // 合起来编码的情况if(tmp >= 10 && tmp <= 26) dp[1]++;// 填表for(int i = 2; i < n; ++i){if(s[i] != '0') // 单独编码的情况dp[i] += dp[i - 1];// 合起来编码的情况tmp = s[i]-'0' + (s[i - 1]-'0')*10;if(tmp >= 10 && tmp <= 26)dp[i] += dp[i - 2];}return dp[n - 1];}
};

优化

​ 与其说是优化,不如说是处理边界问题以及初始化问题的技巧!

​ 从上面这段代码可以发现,其实这个 dp[1] 和我们在 for 循环中判断是一模一样的,只不过 dp[1] 变成了 dp[i],仅此而已。那么这样子冗余的代码其实是不太好看的,写起来也是非常别扭,所以我们来将其优化一下!

​ 其实思路很简单,既然 dp[1] 的判断和后面是一样的,而只有 dp[0] 是需要单独拎出来做额外判断的,那么我们就 先多给 dp 表一个空间,然后将整体往后移动一位,并且将新的 dp[0] 作为虚拟位来填充,如下图所示:

在这里插入图片描述

class Solution {
public:int numDecodings(string s) {// 优化int n = s.size();vector<int> dp(n + 1); // 多开一个空间dp[0] = 1; // 第一位是虚拟位,为了保证第三个字符填表时的正确,这里填1,注意不能为0if(s[0] != '0') // dp[1]相当于原来的dp[0]dp[1] = 1;// 填表,注意是遍历到n,并且原来的关于s的下标都要再减一,因为dp表全体往后移动了一位for(int i = 2; i <= n; ++i){if(s[i - 1] != '0') // 单独编码的情况dp[i] += dp[i - 1];// 合起来编码的情况int tmp = s[i - 1]-'0' + (s[i - 2]-'0')*10;if(tmp >= 10 && tmp <= 26)dp[i] += dp[i - 2];}return dp[n];}
};

在这里插入图片描述

http://www.xdnf.cn/news/1184707.html

相关文章:

  • Uniapp编写微信小程序,绘制动态圆环进度条
  • LIMA:大语言模型对齐的“少即是多”革命——原理、实验与范式重构
  • 软件工程:软件需求
  • 图书推荐-由浅入深的大模型构建《从零构建大模型》
  • 【模型剪枝1】结构化剪枝论文学习笔记
  • k8s-MongoDB 副本集部署
  • XORIndex:朝鲜不断发展的供应链恶意软件再次瞄准 npm 生态系统
  • Kubernetes配置管理
  • Axios基本使用
  • GUI界面已经移植完,添加欠缺字,微调GUI界面说明
  • Kafka运维实战 15 - kafka 重设消费者组位移入门和实战【实战】
  • 时间和空间复杂度
  • 八股文之JVM
  • DNS 服务正反向解析与 Web 集成实战:从配置到验证全流程
  • Day 21: 常见的降维算法
  • 专题:2025电商增长新势力洞察报告:区域裂变、平台垄断与银发平权|附260+报告PDF、原数据表汇总下载
  • 小米8(dipper)刷入kernelSU内核root定制rom系统教程以及安装LSPosed模块
  • Windows-WSL-Docker端口开放
  • FunASR实时多人对话语音识别、分析、端点检测
  • NLP验证自动化脚本优化
  • 从热点到刚需:SmartMediaKit为何聚焦B端视频系统建设?
  • 【lucene】AttributeSource概述
  • Ethereum:Geth + Clef 本地开发环境,如何优雅地签名并发送一笔以太坊交易?
  • Linux 内存深度剖析:栈与堆的底层机制与实战指南
  • 汽车免拆诊断案例 | 2010款奔驰E200 CGI车EPS OFF灯异常点亮
  • MCP 与传统集成方案深度对决:REST API、GraphQL、gRPC 全方位技术解析
  • Linux725 磁盘阵列RAID0 RAID1
  • Linux库——库的制作和原理(1)_回顾动静态库、制作使用库
  • docker-compose:未找到命令的检查步骤和修复
  • 从数据孤岛到融合共生:KES V9 2025 构建 AI 时代数据基础设施