【手撕算法|动态规划系列No.4】leetcode91. 解码方法

news2024/11/13 9:25:49

个人主页:平行线也会相交
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创
收录于专栏【手撕算法系列专栏】【LeetCode】
🍔本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希望对大家有所帮助
🍓希望我们一起努力、成长,共同进步。
在这里插入图片描述

点击直接跳转到该题目

目录

  • 题目描述🥪
  • 算法原理🍔
  • 代码实现🧀
  • 代码优化+代码实现🥖

题目描述🥪

在这里插入图片描述

在这里插入图片描述

算法原理🍔

状态表示:

根据以往做题的经验和,题目描述,我们可以以某个位置为起点或者以某个位置为终点进行分析问题
根据题目要求,状态表示以i位置为结尾dp[i]表示以i位置为结尾时,解码方法的总数。

状态转移方程:

根据以往的经验,我们依然是根据最近的状态来划分问题。
在这里插入图片描述
状态转移方程:dp[i]=dp[i-1]+dp[i-2]

初始化:

为了防止越界问题,所以这里我们对dp[0]和dp[1]进行初始化。
在这里插入图片描述

填表顺序:

综上所述,填表顺序是从左往右进行的。

返回值:

根据题意,我们要求的是整个字符串进行解码的方案的总数,也就是说我们需要解码到最后一个位置才可以。由于最后一个位置是n-1,所以我们最后返回的是dp[n-1]

代码实现🧀

在编写代码时,依然是按照之前的步骤来进行代码的编写,即创建dp表、初始化、填表、返回值

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[0]!='0'&&s[1]!='0') dp[1] += 1;
        int tmp = (s[0]-'0')*10 + (s[1]-'0');
        if(tmp>=10&&tmp<=26) dp[1] += 1;

        for(int i = 2;i < n;i++)
        {
            if(s[i]!='0') dp[i] += dp[i-1];//处理单独编码的情况

            int tmp = (s[i-1]-'0')*10 + (s[i]-'0');//处理第二种情况
            if(tmp>=10&&tmp<=26) dp[i]+=dp[i-2];
        }
        return dp[n-1];
    }
};

代码优化+代码实现🥖

在动态规划dp问题中,我们会经常碰到繁琐的处理边界问题的情况以及初始化问题。所以这里有一个处理边界问题以及初始化的技巧:我们在创建dp表的时候多开一个元素位置的空间。我们把新dp表中的d[0]称之为虚拟节点。
在这里插入图片描述

我们可以看到上述解题代码初始化部分和填表部分代码的相似度有一点高。我们可以将初始化部分的代码放到填表部分来解决这种代码相似度比较高的情况。

在原先的解题代码中我们在初始化dp[1]的时候是最麻烦的,而现在由于我们在创建dp表的时候多开辟了一块空间,所以我们只需要对新dp表中的dp[0]和dp[1]进行初始化即可,此时就把原dp表中的dp[1]的初始化转换为填表的逻辑中(相当于把原来dp[1]的初始化去掉了,直接在新dp表中填表即可)。

如果想要保证后面的填表时正确呢?请看:
1.虚拟节点(即新dp表中的dp[0])中的值要保证后面的填表是正确的。
2.一定要注意下标的映射关系。
这里举一个例子:现在我们要填写新dp表中的dp[2],由于dp[i]=dp[i-1]+dp[i-2],所以我们需要dp[0]dp[1]的值,而dp[1]中的值和原dp表中的dp[0]的求取逻辑是一模一样的,所以现在我们只需要关心新dp表中dp[0]应该怎样初始化。这里一般情况下dp[0]这里是要初始化成0。但是根据本题的题目要求,dp[0]并不能初始化成0,而是初始化成1

现在来解释为什么新dp表中的dp[0]不能初始化为0
还是以新dp表中dp[2]的位置为例,由前面分析得知需要知道新dp表中dp[0]的值,对应的原字符串s[0]和s[1]拼起来后可以解码成功,既然解码成功了,所以就需要加上dp[0]的值(即加上1),即找到了一种解码方式,如果我们初始化为0的话,就相当于忽略了这一种解码方式。

在这里插入图片描述

请看优化后的解题代码:

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';//与原dp表中dp[0]位置的初始化的逻辑是一样的,这里要注意下标的映射关系

        for(int i = 2;i <= n;i++)
        {
        	//注意s字符串的映射关系
            if(s[i-1]!='0') dp[i] += dp[i-1];//处理单独编码的情况

            int tmp = (s[i-2]-'0')*10 + (s[i-1]-'0');//处理第二种情况
            if(tmp>=10&&tmp<=26) dp[i]+=dp[i-2];
        }
        return dp[n];
    }
};

好了,本文就到这里啦!
再见啦,友友们!!!

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测试:系统测试

1 系统测试的概念 系统测试&#xff08;System Testing&#xff09;的定义&#xff1a;将已经集成好的软件系统&#xff0c;作为整个基于计算机系统的一个元素&#xff0c;与计算机硬件、外设、某些支持软件、数据和人员等其他系统元素结合在一起&#xff0c;在实际运行&#…

HDLBits刷题笔记8:Circuits.Sequential Logic.Latches and Flip-Flops

D flip-flop module top_module (input clk,input d,output reg q );always (posedge clk)q < d; endmoduleD flip-flops 建立一个8bit的D触发器 module top_module (input clk,input [7:0] d,output reg [7:0] q );always (posedge clk)q < d; endmoduleDFF with res…

GDAL 图像直方图统计

文章目录 一、简介二、实现代码三、实现效果参考资料 一、简介 这里使用一种简单的方式来计算图像中的像素值直方图分布。计算过程如下所述&#xff1a; 第一种方式&#xff1a; 1、首先将图像变为一维数组&#xff08;reshape&#xff09;&#xff0c;并将数组中的数值进行排序…

vue点击盒子一步一步滚动

vue点击盒子一步一步滚动 HTML <div class"course_detail"><div class"arrow" v-if"index 0" click"step"></div><div class"lightArrow" v-else click"step"></div><div clas…

自定义的车牌号键盘组件

<template><view class"keyboard-wrap" v-if"kbShow"><view class"head"><view class"done" tap"done"><text class"iconfont iconxiala-"></text>关闭</view></vi…

2. 注册platform

这里先分析platform 对应的dts内容如下 i2s0_8ch: i2sff800000 {compatible "rockchip,rv1126-i2s-tdm";reg <0xff800000 0x1000>;interrupts <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;clocks <&cru MCLK_I2S0_TX>, <&cru MCLK_I2S0_RX&g…

JAVA开发( 腾讯云消息队列 RocketMQ使用总结 )

一、问题背景 之所以需要不停的总结是因为在java开发过程中使用到中间件实在太多了&#xff0c;久久不用就会慢慢变得生疏&#xff0c;有时候一个中间很久没使用&#xff0c;可能经过了很多版本的迭代&#xff0c;使用起来又有区别。所以还是得不断总结更新。最近博主就是在使用…

睿铂相机同步性控制技术解析

极客睿铂 前几期睿铂给大家分享了一些倾斜相机背后的技术&#xff0c;主要都是的关于镜头光学方面的。但实际上倾斜摄影相机还有很多其他关键性技术有待突破&#xff0c;任何技术的发展都不能一蹴而就&#xff0c;需要根据客户的问题反馈&#xff0c;发现新的问题并解决问题&a…

自定义MVC架构【下】

目录 一、前言 二、导出自定义MVC架包 三、使用自定义MVC架包 四、优化增删改查Dao层及Servlet 1.优化增删改查Dao层 2.优化增删改查Servlet代码 五、案例实操 1.将PageTag自定义标签进行配置 2.jsp页面环境搭建 3.案例演示 一、前言 在上篇中&#xff0c;我们已经优化…

ARM架构(寄存器点灯)

文章目录 前言一、LED原理图二、使用寄存器点灯的步骤三、如何操作寄存器四、实际操作1.使能GPIO端口2.将引脚设置为输出模式3.设置输出状态 五、全部代码总结 前言 本篇文章我们来讲解一下如何使用寄存器点亮一个LED灯&#xff0c;一般对于新人来说都是使用HAL库或者标准库来…

SpringBoot3【④ 基础特性】

1. SpringApplication 1.1. 自定义 banner 类路径添加banner.txt或设置spring.banner.location就可以定制 banner推荐网站&#xff1a;Spring Boot banner 在线生成工具&#xff0c;制作下载英文 banner.txt&#xff0c;修改替换 banner.txt 文字实现自定义&#xff0c;个性化…

操作系统面试知识点

1、进程、线程和协程的区别和联系 1、进程是资源调度的基本单位&#xff0c;运行一个可执行程序会创建一个或多个进程&#xff0c;进程就是运行起来的可执行程序 2、线程是程序执行的基本单位&#xff0c;是轻量级的进程。每个进程中都有唯一的主线程&#xff0c;且只能有一个…

机器学习第三课(sklearn接口)

一、sklearn基本知识 中文官网 英文官网 注意&#xff1a;sklearn第三方模块的安装 要用pip install scikit-learn from sklearn.neighbors import KNeighborsClassifier # 1 准备数据 # 训练集的特征数据 2维 x [[-2],[-1],[2],[3],[4]] # 训练集的目标数据 1维 y [0,0,1,…

HTML培训心得体会五篇(合集)

HTML5培训心得一 关于html5培训心得总结? 一&#xff1a;了解HTML5前端开发技术? ?? HTML?指的是超文本标记语言?(Hyper?Text?Markup?Language)&#xff0c;标记语言是一套标记标签?(markup?tag)&#xff0c;HTML?使用标记标签来描述网页。HTML5区别于HTML的标…

北京大学2015计算机学科夏令营上机考试(未完)

A:整数的个数 #include<iostream> using namespace std; int main(){int k,a;cin>>k;int sum10,sum20,sum30;for(int i0;i<k;i){cin>>a;if(a1) sum1;if(a5) sum2;if(a10) sum3;}cout<<sum1<<endl<<sum2<<endl<<sum3;retur…

quiche编译

netty http3使用了rust语言的quiche&#xff0c;quiche使用了c语言的boringssl&#xff0c; 网上没有找到编译好的quiche&#xff0c;只能自己搭建rust环境编译 1、rust安装 见官网https://www.rust-lang.org/tools/install 我是用的是windows的ubuntu&#xff0c;所以直接使…

苹果市值再度突破3万亿美元

KlipC报道&#xff1a;当地时间周五&#xff0c;苹果市值再度突破3万亿美元&#xff0c;这是近43年来&#xff0c;苹果第二次市值达到3万亿。 KlipC的合伙人Andi Duan表示&#xff1a;“得益于苹果股价上涨&#xff0c;以及硅谷银行引发的金融市场动荡&#xff0c;再加上高端IP…

【嵌入式Qt开发入门】如何创建并连接信号与槽

创建信号 我们先新建一个项目&#xff0c;命名为 signal_slot_example&#xff0c;如果还不会新建项目&#xff0c;请回到 【嵌入式Qt开发入门】初识信号与槽查看项目如何建立的。取消勾选*ui 文件&#xff0c;其他步骤不变。 由于信号只需声明&#xff0c;无需定义。所以我们只…

Mac端显示服务器上show的内容

Mac端显示服务器上show的内容 1. 需求描述 在Mac端&#xff08;终端和PyCharm中&#xff09;编写代码&#xff0c;在服务器端运行程序。需要在Mac端显示服务器端运行的内容&#xff0c;比如&#xff0c;运行的视频等。 2. 常见报错 SSH 运行命令时报错示例。 (cv) czjing…

旋转链表:给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

解题思路&#xff1a; 1.找到原链表的最后一个节点 2.计算链表长度n 3.将原链表的尾节点指向链表的头节点&#xff0c;使链表形成环 4.新链表根据画图可知&#xff0c;会在环的&#xff08;n-k%n&#xff09;的地方断开&#xff0c;这个节点newtail是新链表的尾节点 5.将新…