【动态规划】:泰波那契模型_解码方法

这篇具有很好参考价值的文章主要介绍了【动态规划】:泰波那契模型_解码方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

朋友们、伙计们,我们又见面了,本专栏是关于各种算法的解析,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!

C 语 言 专 栏:C语言:从入门到精通

数据结构专栏:数据结构

个  人  主  页 :stackY、

C + + 专 栏   :C++

Linux 专 栏  :Linux

【动态规划】:泰波那契模型_解码方法,初阶算法,动态规划,算法,解码方法

目录

1. 题目解析

2. 算法原理

2.1 状态表示

2.2 状态转移方程

2.3 初始化

2.4 填表顺序

2.5 返回值

3. 代码实现

4. 算法复杂度 

5. 优化边界情况以及初始化 

5.1 优化之后代码 


1. 题目解析

Leetcode91.解码方法:https://leetcode.cn/problems/decode-ways/description/

一条包含字母 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 只包含数字,并且可能包含前导零。

本题采用动态规划的思想,以某一位置为开始,或者以某一位置为结束,要注意的是:

例如:

06没有解码方式,因为单独的0不能解码,并且06组合起来也不能解码,06和6并不等价。

60也没有解码方式,6单独有解码方式,但是0没有,并且二者结合60也没有解码方式。 

262有两种解码方式,依次单独解码(1),26组合解码(2),但是62组合没有解码方式。

那么就表明:

一个数要能单独解码就要在'1' ~ '9' 之间

两个数组合一起能解码就要在'10' ~ '26' 之间

2. 算法原理

2.1 状态表示

根据题目要求:

要求的是总共的解码数,那么假设一共有i个数

那么我们以i位置为结尾时,所得的解码的方法就是要求的解码方法总数。

因此:dp[i] 就表示解码的方法数。

2.2 状态转移方程

根据最近的一步划分问题:

dp[i]位置的解码数就是:①s[i]单独解码数

                                       ②s[i-1]和s[i]组合起来的解码数

①如果s[i]能单独解码,那么此时的解码数就是dp[i-1]时的解码数,如果不能单独解码,那么之前的工作都作废了,总的解码数为0的。

②如果s[i-1]和s[i]组合起来能解码,那么此时的解码数就是dp[i-2]时的解码数,如果组合起来不能解码,那么就为0。

因此如果两种方式都可以解码成功:dp[i] = dp[i-1] + dp[i-2]

【动态规划】:泰波那契模型_解码方法,初阶算法,动态规划,算法,解码方法

2.3 初始化

为了防止越界,求dp[i]就要知道dp[i-1]和dp[i-2],所以需要将dp[0]和dp[1]初始化

dp[0]就是s[0]位置的解码数,那么只有0和1两种情况,如果s[0]能单独解码,就是1,不能则是0。

dp[1]就是s[1]位置的解码数,这里存在两种情况,如果s[0]和s[1]能单独解码就算一种,如果s[0]和s[1]组合起来能解码也是一种,如果s[1]单独都不能解码就是0。

因此dp[1]的解码方法是0或1或2。

【动态规划】:泰波那契模型_解码方法,初阶算法,动态规划,算法,解码方法

2.4 填表顺序

从左向右

2.5 返回值

dp[n-1]

3. 代码实现

class Solution 
{
public:
    int numDecodings(string s) 
    {
        int n = s.size();
        // 1. 创建dp表
        vector<int> dp(n);   

        // 2. 初始化
        dp[0] = s[0] != '0';
        // 边界情况
        if(n == 1) return dp[0];

        if(s[0] != '0' && s[1] != '0') dp[1] += 1;
        int ret = (s[0] - '0')*10 + s[1] - '0';
        if(ret >= 10 && ret <= 26) dp[1] += 1;
        
        // 3. 填表
        for(int i = 2; i<n; i++)
        {
            // 单独解码
            if(s[i] != '0') dp[i] += dp[i-1];
            int ret = (s[i-1] - '0')*10 + s[i] - '0';
            // 组合解码
            if(ret >= 10 && ret <= 26) dp[i] += dp[i-2];
        }

        // 4. 返回值
        return dp[n-1];
    }
};

4. 算法复杂度 

时间复杂度:O(N)

空间复杂度:O(N)

5. 优化边界情况以及初始化 

通过上面的代码可以发现: 初始化部分与填表部分逻辑类似代码冗余,所以可以做以优化

【动态规划】:泰波那契模型_解码方法,初阶算法,动态规划,算法,解码方法

我们在创建dp表时可以多创建一个空间,只需要对这个空间进初始化就可以优化繁琐的初始化过程:

【动态规划】:泰波那契模型_解码方法,初阶算法,动态规划,算法,解码方法

既然多开了一个空间,那么就需要注意两个问题:

1. 初始化虚拟节点的值,要保证后面的填表是正确的;

2. 下标映射的关系。 

下面,我们分别来对这两个问题进行研究:

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

因为我们多开了一个空间,这个空间的值也就意味着后面的值正确与否,我们需要根据题目要求和状态表示来初始化这个虚拟空间的值:

状态表示:dp[i]表示解码方法数

那么这个虚拟空间的值应该被设置为1  ->  dp[0] = 1

那么为什么呢?

在计算dp[2]时,如果可以与前一个组合起来解码,那么需要加上dp[i-2],这样就正好是一种方法。

2. 下标映射的关系

由于我们多创建了一个空间,那么在填表的时候s中的下标就要统一减一。

【动态规划】:泰波那契模型_解码方法,初阶算法,动态规划,算法,解码方法

5.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++)
        {
            // s的下标要对应-1
            if(s[i - 1] != '0') dp[i] += dp[i-1];
            int ret = (s[i-2] - '0')*10 + s[i - 1] - '0';
            if(ret >= 10 && ret <= 26) dp[i] += dp[i-2];
        }
        //多开一个空间所以返回第n个位置即可
        return dp[n];
    }
};

 【动态规划】:泰波那契模型_解码方法,初阶算法,动态规划,算法,解码方法

 

朋友们、伙计们,美好的时光总是短暂的,我们本期算法的分享就到此结束,欲知后事如何,请听下回分解~,最后看完别忘了留下你们弥足珍贵的三连喔,感谢大家的支持! 文章来源地址https://www.toymoban.com/news/detail-826862.html

到了这里,关于【动态规划】:泰波那契模型_解码方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【学会动态规划】第 N 个泰波那契数(4)

    目录 动态规划怎么学? 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后: 学习一个算法没有捷径,更何况是学习动态规划, 跟我一起刷动态规划算法题,一起学会动态规划! 这道题目不难理解,就是根据题目给的字

    2024年02月16日
    浏览(38)
  • 【学会动态规划】第 N 个泰波那契数(1)

    目录 动态规划怎么学? 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 4. 空间优化 写在最后 学习一个算法没有捷径,更何况是学习动态规划, 跟我一起刷动态规划算法题,一起学会动态规划! 题目链接:1137. 第 N 个泰波那

    2024年02月15日
    浏览(46)
  • LeetCode第 N 个泰波那契数 (认识动态规划)

    链接: 第 N 个泰波那契数 编写代码 代码空间优化 一般像这种情况我们可以使用滚动数组的方式来解决空间的问题

    2024年02月15日
    浏览(39)
  • 动态规划解决泰波那契数列,爬楼梯最小花费问题

    做题之前我们需要先搞清楚解决动态规划的几个步骤 1 状态表示,准备一个dp表 2 状态转移方程  3 初始化 4 填表 5 返回值 步骤1 状态表示,准备dp表 dp[0] dp[1] dp[2] dp[3] dp[4] = dp[0]+dp[1]+dp[3] 步骤2 状态转移方程表示 dp[i] = dp[i-1]+dp[i-2]+dp[i-3] 步骤3 4 5 都是对代码的细节处理,代码

    2024年02月03日
    浏览(35)
  • LeetCode、1137. 第 N 个泰波那契数【简单,动态规划】

    博主介绍:✌目前全网粉丝2W+,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖技术内容:Java后端、算法、分布式微服务、中间件、前端、运维、ROS等。 博主所有博客文件目录索引:博客目录索引(持续更新) 视频平台:

    2024年02月22日
    浏览(53)
  • Java动态规划LeetCode1137. 第 N 个泰波那契数

             方法1:通过动态规划解题,这道题也是动态规划的一道很好的入门题,因为比较简单和容易理解。 代码如下:         动态规划的解题步骤分为5步                 1.状态表示                 2.状态转移方程                 3.初始化                 4.填表

    2024年02月13日
    浏览(48)
  • 【动态规划刷题 1 】 第N个泰波那契数&& 三步问题

    链接: 第N个泰波那契数 1137 . 第 N 个泰波那契数 泰波那契序列 Tn 定义如下: T0 = 0, T1 = 1, T2 = 1, 且在 n = 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2 给你整数 n,请返回第 n 个泰波那契数 Tn 的值。 示例 1: 输入:n = 4 输出:4 解释: T_3 = 0 + 1 + 1 = 2 T_4 = 1 + 1 + 2 = 4 示例 2: 输入:n = 25 输出:

    2024年02月15日
    浏览(40)
  • 【手撕算法|动态规划系列No.1】leetcode1137. 第 N 个泰波那契数

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

    2024年02月11日
    浏览(56)
  • 【动态规划】斐波那契数列模型

    冻龟算法系列之斐波那契数列模型 动态规划(英语:Dynamic programming,简称 DP) ,是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质

    2024年02月09日
    浏览(65)
  • 【算法学习】斐波那契数列模型-动态规划

            我在算法学习过程中,针对斐波那契数列模型的动态规划的例题进行了一个整理,并且根据标准且可靠一点的动态规划解题思路进行求解类似的动归问题,来达到学习和今后复习的必要。         所谓的斐波那契数列模型,即当前状态的值等于前两种状态的值之和。

    2024年02月04日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包