leetcode91.解码方法(动态规划)

问题描述:

一条包含字母 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 位 的整数。

示例一:

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

示例二:

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

示例三:

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

问题解读:

本题主要是将A~B这26个字母等价成1~26个数,然后在给你一段数字字符串,让你通过字母替代

这些数字,最后返回代替的所有的结果的个数。

问题解决:

对应使用的还是动态规划的方法:

1.状态表示

dp[i]等于以i未结尾时,所有的解码方法

2.状态转移方程

假设在i下标之前的两个元素分别是a和b,对dp[i]的结果有两种情况:

1.s[i]单独解码,满足的条件:1 <= a <= 10,对应dp[i] += dp[i - 1]

如果不满足条件,说明a == 0对应无法进行映射,直接返回0

2.s[i] 和s[i - 1]联合解码,满足的条件:10 <= 10*a + b <= 26,对应dp[i] += dp[i - 2]

如果不满足条件,说明无法用英文字母完成映射,直接跳过dp[i] 不加不减。

对应的转台转移方程需要经过判断而存在许多不同,所以这里不列出了。

3.初始化一些值:

根据上述的状态转移方程的描述,知道需要初始化dp[0]和dp[1]。

dp[0]的初始化:

只需要判断dp[0]的值是否满足 1<= dp[0] <= 9,

满足:dp[0] = 1

不满足:说明这一串数字中存在0,直接返回0

dp[1]的初始化:

需要进行两次判断,第一次判断:

需要判断dp[1]的值是否满足 1<= dp[0] <= 9,

满足:dp[1] += dp[0]

不满足:直接返回0

再判断dp[0] 和dp[1]组合是否满足 10 <= 10*dp[0] + dp[1] <= 26,

满足:dp[1] += 1

不满足:dp[1]不加不减

4.填表顺序:

从左向右

5.返回值:

dp[n - 1]

对应的代码如下:

class Solution 
{
public:int numDecodings(string s) {int n = s.size();vector<int> dp(n);//初始化前两个位置dp[0] = s[0] != '0';if(n == 1){return dp[0];}if(s[1] <= '9' && s[1] >= '1'){dp[1] += dp[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] <= '9' && s[i] >= '1'){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];}
};

大家仔细观察一下这段代码,发现这两段有很多冗余:
 

那么如何使代码更简洁呢?

我们可以将dp数组多开一个字节,这样就可以将求第二个节点的解法放在循环里面了,从而减少代

码的行数,将第一为作为虚拟头节点那么问题就来了:

1.如何确定虚拟头节点的值是结果是正确的?

我们只需设想现在在求第三个节点的解法有多少个,当第三个节点和前一个节点的组合成立的时候

需要用到虚拟头节点的数字,而此时只要将解法+1即可,所以需要再虚拟头节点存的是数字1.

2.下标的映射如何变化:

应为相当于将dp中的所有的下标都+1了,所以对应到s的映射就需要将下标-1,就是对应要得到的

数字,这不也是添加头节点的关键,不然全盘皆输,所以可以将代码修改如下:

class Solution 
{
public:
//优化后int numDecodings(string s) {int n = s.size();vector<int> dp(n + 1);dp[0] = 1;dp[1] = s[1 - 1] != '0';for(int i = 2;i <= n;i++){if(s[i - 1] != '0'){//处理单独编码的情况dp[i] += dp[i - 1];}int t = (s[i - 2] - '0') * 10 + s[i - 1] - '0';if(t >= 10 && t <= 26){dp[i] += dp[i - 2];}}return dp[n];}
};

这样代码就不冗余了,一定要注意s的下标的微妙变化,将所有的s[i] 都变成了s[i - 1],以此类推,

这样的代码虽然代码量下来了,但是么有任何下路上的优化,只是将初始化的值放在循环里进行了

初始化。
 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何才能做好源代码防泄密

目前很多企业都拥有自己的研发机构&#xff0c;其研发成果往往体现在源代码和技术文档方面&#xff0c;这些核心机密&#xff0c;如何防止研发参与人员泄密&#xff0c;如何防止核心成员把研究成果带走另立山头&#xff0c;或者提供给竞争对手&#xff0c;是一个很现实的一个问…

Vue-路由介绍

目录 一、思考引入 二、路由介绍 一、思考引入 单页面应用程序&#xff0c;之所以开发效率高&#xff0c;性能高&#xff0c;用户体验好&#xff0c;是因为页面按需更新。 而如果要按需更新&#xff0c;首先需要明确&#xff1a;访问路径和组件的对应关系。该关系通过路由来…

Vue CLI配置代理、2.0、3.0

一、vue cli2.0 代理配置 proxy: {/api:{target: "http://localhost:8067",pathRewrite: {/api: }}, } 一、vue cli3.0 代理配置 proxy: {/api: {target: http://localhost:8067,pathRewrite: {/api: }} }

【C++】滑动窗口:最大连续1的个数

1.题目 2.算法思路 其实在做这道题的时候并不需要真的把0翻转成1&#xff0c;只需要找到最长的子数组且该子数组中0的个数不大于K&#xff0c;就可以了&#xff01; 当然我们首先想到的是暴力穷举法&#xff1a; 找到所有符合题意的子数组&#xff0c;跳出最长的那个就可以了…

NodeMCU ESP8266 操作 SSD1306 OLED显示屏详解(图文并茂)

文章目录 1 模块介绍2 接线介绍3 安装SSD1306驱动库4 源码分析4.1 硬件兼容性4.2 可能存在的问题总结1 模块介绍 我们将在本教程中使用的OLED显示屏是SSD1306型号:单色0.96英寸显示屏,像素为12864,如下图所示。 OLED显示屏不需要背光,这在黑暗环境中会产生非常好的对比度。…

仓库管理系统需求调研要点

仓库管理系统需求调研 一、仓库的作用 仓库分类 原材料仓库&#xff1a;用于存放生产所需的原材料和零部件&#xff0c;需要保持原材料的质量和数量稳定。半成品仓库&#xff1a;存放生产过程中的半成品和在制品&#xff0c;需要保持良好的生产流程和及时出库。成品仓库&#x…

微信小程序和微信H5微商城的区别,微信商城主要有哪些类型

什么是微信小程序&#xff1f; 微信小程序的推出是一场革命&#xff0c;它为用户提供了应用程序中的应用程序。这些轻量级的、不到10 MB的实用程序改变了微信的体验&#xff0c;使其从一个纯粹的消息传递平台转变为一个包罗万象的数字宇宙。截至2024年初&#xff0c;WeChat拥有…

SPSS多元线性回归

&#xff08;要满足&#xff09;模型的假设条件需要对数据进行怎样处理&#xff1f;&#xff1f; 为了使数据满足多元线性回归的条件&#xff0c;通常需要进行以下预处理步骤&#xff1a; 1. 数据清洗&#xff1a;处理缺失值、异常值和重复值&#xff0c;确保数据质量。 2. 特…

C/C++ 初级球球大作战练手

效果演示&#xff1a; https://live.csdn.net/v/385490 游戏初始化 #include <stdbool.h> #include<stdio.h> #include<stdlib.h> #include<time.h> #include<graphics.h> #include <algorithm> #include<math.h> #include<mmsy…

【刷题篇】双指针(二)

文章目录 1、有效三角形的个数2、查找总价格为目标值的两个商品3、三数之和4、四数之和 1、有效三角形的个数 给定一个包含非负整数的数组 nums &#xff0c;返回其中可以组成三角形三条边的三元组个数。 class Solution { public:int triangleNumber(vector<int>& n…

C51版本Keil + STC-ISP 实现第一盏灯,从创建到实现

创建项目 1. 新建项目 Project -> New uVision Project 2.1 新建文件夹 2.2 输入文件名称, 并保存 3.1 选择当前位STC芯片的开发板&#xff0c;选择STC MCU Database 搜素具体芯片型号&#xff0c;进行配置&#xff1a; 3.2 选择通过搜索框搜索到stc相关芯片信息 如果st…

OpenCV 入门(四)—— 车牌号识别

OpenCV 入门系列&#xff1a; OpenCV 入门&#xff08;一&#xff09;—— OpenCV 基础 OpenCV 入门&#xff08;二&#xff09;—— 车牌定位 OpenCV 入门&#xff08;三&#xff09;—— 车牌筛选 OpenCV 入门&#xff08;四&#xff09;—— 车牌号识别 OpenCV 入门&#xf…