剑指Offer题解 | #把数字翻译成字符串# 动态规划

题目地址:把数字翻译成字符串

【动态规划】
①分析题目:能够译码的数字不会大于26,即有效的译码范围为 [1,26]。

②确定状态:以数组 “12345” 为例,首先要明确两点:

依题意可知,数组中所有的数字都必须参与译码,比如数组 “1234” 的某一种译码方式为 “1,2,3,4",那么当数组尾再添加一个元素 “5” 时,刚才的译码方式就会变为 “1,2,3,4,5”,即 “1,2,3,4” 和 “1,2,3,4,5” 是同一种译码方式。

由于所有数字都要参与译码,所以只要译码方式中存在个位数 “0”,那么就都是无效的。

当新加入一个数字"5" 时,其除了可以单独作为一个数字参与译码外,也可以与其左边的数字组成数字组合后再参与译码,即 “45” ,然后此时有多少种译码方式就取决于剩余的数字 即 “123” 了,这和前面所说的是同一个道理,只是此时把 “4"和"5” 看作是一个整体,可以理解为:原本数组 “123” 存在某种译码方式为 “1,2,3”,现在加入 “45”,译码方式就变成了 “1,2,3,45”。

由于有效的译码范围为 [1,26],所以新加入的数字 “5” 只需要考虑与其左边的数字组成两位数组合,无需再考虑组成更大的组合了,比如三位数 “345” 等等。

数字组合必须是十位数,比如 “0"和"2” 组成的 “02” 也是不符合译码要求的。

理解了上面两点后,现在我们从数组 “12345” 的子串"1"开始分析,然后逐步往后添加元素,设数组 x 有 f(x) 种有效的译码方式:

当数组为 “1” 时,有以下译码方式:

①1

f(“1”)=1

接着加入数字"2",数组为 “12” 时,有以下译码方式:

①1,2

②12

f(“12”)=2

其中第①种是从 数组 “1” 的译码方式 演变过来的,就是在其基础上再加上单个数字 “2”。

接着加入数字"3",数组为 “123” 时,有以下译码方式:

①1,2,3

②12,3

③1,23

f(“123”)=3

其中第①、②种是从 数组 “12” 的译码方式 演变过来的,就是在其基础上再加上单个数字 “3”;

而第③种是从 数组 “1” 的译码方式 演变过来的,就是在其基础上再加上数字组合 “23”。

接着加入数字"4",数组为 “1234” 时,有以下译码方式:

①1,2,3,4

②12,3,4

③1,23,4

④1,2,34

⑤12,34

其中第①、②、③种是从 数组 “123” 的译码方式 演变过来的,就是在其基础上再加上单个数字 “4”;

而第④、⑤种是从 数组 “12” 的译码方式 演变过来的,就是在其基础上再加上数字组合 “34”;

由于 “34” 不在有效译码的范围内,所以这两种译码方式会被抛弃掉。

f(“1234”)=3

可见,数组 “1234” 的译码方式 是由 数组 "123"的译码方式 和 数组 "12"的译码方式 组成的。

根据上面的分析,当数组继续扩张到 “12345” 时,那么其译码方式就为:

当新加入的数字 “5” 单独作为个位数参与译码时,此时的译码方式 就等同于 数组 “1234” 的译码方式,这组译码方式是有效的,因为个位数 “5” 在有效的译码范围内;

而 “5” 与其前一位数字组成十位数 “45” 时,此时的译码方式 就等同于 数组 “123” 的译码方式,而这组译码是否有效则取决于 “45” 是否在有效的译码范围内。

即 f(“12345”) = f(“12345” - “5”) + f(“12345” - “45”) = f(“1234”) + f(“123”) = 3+3 = 6,但是由于 “45” 不在有效的译码范围内,所以 f(“123”) 的结果不能算在内,所以最终结果应该为3。

可见,枚举到某位数字时,此时有多少种译码方式,可以由之前的译码方式相加得出,即当前的状态可以利用之前的状态,这是典型的动态规划。

③状态转移方程:f(x)=f(x-1)+f(x-2)(其中 x 表示数组长度,f(x) 表示有多少种有效的译码方式;是否加上 f(x-1) 取决于 nums[x] 是否在 [1,9] 内,即 nums[x] 需要满足不为0;是否加上 f(x-2) 则取决于 nums[i-1] 与 nums[i] 的数字组合是否在 [10,26] 内)

时间复杂度:O(N) ,需要遍历一次数组

空间复杂度:O(N) ,需要声明一个状态数组记录f(x)

C#代码:

class Solution {
    public int solve (string nums) {
        int[] codesNum=new int[nums.Length]; //状态数组,记录f(x)
        //初始条件:
        if(nums[0].ToString() != "0"){
            codesNum[0]=1;
        }
        //从数组第2位枚举到最后一位:
        for(int i=1;i<nums.Length;++i){
            //判断nums[i]是否不为0
            if(nums[i].ToString() != "0"){
                codesNum[i]+=codesNum[i-1];
            }
            //判断nums[i-1]与nums[i]的数字组合是否在[10,26]内
            int temp=int.Parse(nums[i-1].ToString() + nums[i].ToString());
            if(temp >= 10 && temp <= 26){
                if(i==1){ //即f(2),因为不存在f(0),所以需要特殊处理:
                    codesNum[i]+=1;
                }else{
                    codesNum[i]+=codesNum[i-2];
                }
            }
        }
       return codesNum[nums.Length-1];
    }
}

剑指offer(第二版) Python3实现 剑指offer Python题解 03.数组中重复的数字 04.二维数组中的查找 05.替换空格 06.从尾到头打印链表 07.重建二叉树 08.二叉树的下一个节点 09.用两个栈实现队列 10.斐波那契数列 11.旋转数组中的最小数字 12.矩阵中的路径 13.机器人的运动范围 14.剪绳子 15.二进制中 1 的个数 16.数值的整数次方 17.打印从1到最大的n位数 18.删除列表中重复的... 阅读详情

相关推荐

剑指offer》41、把数字翻译成字符串

offer41的题目是给定一个数字,然后按照如下规则把它翻译为字符串: 0翻译成”a”,1翻译成”b”,……,11翻译成”l”,……,25翻译成”z”。 这样一来,一个数字可能有多个翻译——例如12258有5种不同的翻译,它们分别是”bccfi”、”bwfi”、”bczi”、”mcfi”和”mzi”。 现在给出一个数字,要求其总的翻译方法数。 递归 本来这题我是想和“最长不含重复字符的字符串”,以及“第一个只出现一次的字符”放在一起讲的,但是后来发现是完全不一样的问题。“把数字翻译成字符串”的核心在于将原问

IceelfLuo的博客 229

剑指offer:把数字翻译成字符串

题目要求:给定一个数字,按照如下规则翻译成字符串:0翻译成“a”,1翻译成“b”...25翻译成“z”。一个数字有多种翻译可能,例如12258一共有5种,分别是bccfi,bwfi,bczi,mcfi,mzi。实现一个函数,用来计算一个数字有多少种不同的翻译方法。 # -*- coding: utf-8 -*- # @Time : 2019-07-10 21:13 # @Autho...

188

剑指 Offer 46. 把数字翻译成字符串 - leetcode 剑指offer系列

题目难度: 中等 原题链接 今天继续更新剑指 offer 系列, 老样子晚上 6 点 45 分准时更新公众号 每日精选算法题, 大家记得关注哦~ 另外在公众号里回复 offer 就能看到剑指 offer 系列当前连载的所有文章了 题目描述 给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。 0 <= num &.

随便发挥的博客 372

剑指Offer系列46】把数字翻译成字符串

文章目录题目代码PythonC++ 题目 给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。 示例 1: 输入: 12258 输出: 5 解释: 12258有5种不同的翻译,分别是"bccfi", “bwfi”, “bczi”, “mcfi"和"mzi” 提示: 0 <= num < 231 代码 Python #

小陈说CV的博客 170

剑指offer 46题 把数字翻译成字符串

""" 面试题46. 把数字翻译成字符串 给定一个数字,我们按照如下规则把它翻译为字符串 :0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。 一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。 示例 1: 输入: 12258 输出: 5 解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi" """ class Solution: def tran

码农ZZK的博客 307

[剑指Offer] 46_把数字翻译成字符串

题目 给定一个数字,我们按照如下规则把它翻译位字符串:0 = ‘a’; 1 = ‘b’;…; 25 = ‘z’,一个数字可能有多种翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。 例: 12258,有5种翻译:“bccfi”, “bwfi”, “bczi”, “mcfi”, “mzi”。 思路 按书上理解,每一位数字有2种可能,单独翻译和与后一位合并翻译,因此f(i) =...

热辣芒果园 457

剑指 Offer 46. 把数字翻译成字符串

剑指 Offer 46. 把数字翻译成字符串 给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。 示例 1: 输入: 12258 输出: 5 解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi" 解法1: 递归 class Solution: .

哈哈哈的博客 158

剑指Offer】把数字翻译成字符串

题目 给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。 思路 这道题抽象为树模型后就是:求一颗二叉树从根结点到达叶子结点的路径总数。 因为每次可能的选择都只有两个,犹如二叉树的两个分支。栗如: 对于数字 13...

hanmin822的博客 210

动态规划剑指offer系列题解---把数字翻译成字符串

记录刷题的过程。该系列默认采用python语言。 1、问题描述: 2、数据结构字符串动态规划 3、题解: 方法1:转化为字符串 动态规划: 先从最后一个状态考虑,如果前面两个字符不在“10”和“25”之间,那么就等于减去一个字符的数量;古国前面两个字符在“10”和“25”之间,则就等于减去一个字符和减去两个字符的数量之和,写出转移方程 class Solution: def translateNum(self, num: int) -> int: #动态规划字符串

weixin_42042056的博客 223

剑指offer刷题笔记

最近LeetCode上的《剑指offer》的题刷的差不多了,只剩几道无聊的题了。现在把做题过程中的记录放在这里,作为将来查看的笔记,也同时欢迎大家指出其中的不当之处(QQ)。虽然博主现在仍然没有拿到offer,但应该正如二师兄所言“放屁添风”,相信也是有些许的参考意义的。 Contens04 二维数组中的查找我的解法官方给出的线性解法05 替换空格我的解法官方解法06 从尾到头打印链表我的解法官方解法07 重建二叉树我的解法官方递归解法官方迭代解法09 用两个栈实现队列我的解法网友的解法10 青蛙跳台阶问题

仰起脸笑得像满月 1128

剑指 Offer 46 把数字翻译成字符串 NC116 把数字翻译成字符串

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。 示例 1: 输入: 12258 输出: 5 解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi" 提示: 0 <= num < 231 解题思路: 我们可以用 f(i)表示以....

麦格芬230的博客 246

数字翻译成字符串python_LeetCode By Python: 剑指Offer 46. 把数字翻译成字符串

题目给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。示例 1:输入: 12258输出: 5解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"提示:0 ...

weixin_39802814的博客 128

算法(21)-leetcode-剑指offer5

leetcode-剑指offer-443.面试题43-1~n整数中1出现的次数44.面试题44-数字序列中某一位的数字45.面试题45-把数组排成最小的数-快排变种46.面试题46-把数字翻译成字符串47.面试题47-礼物的最大价值-dp48.面试题48-最长不含重复字符的子字符串-滑动窗口法49.面试题49-丑数-自底向上递归50.面试题50-第一个只出现一次的字符-hash表51.面试题52-两个链表的第一个公共节点-双指针技巧52.面试题53-在排序数组中找数字54.面试题53-2-0~n-1中的缺失

sinat_40624829的博客 345

剑指 Offer 46. 把数字翻译成字符串 动态规划 回溯

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。 示例 1: 输入: 12258 输出: 5 解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi" 回溯 class Solution: def translateNum(self, num: int) -&

口袋里的星星的博客 174

[[EVD]] - 剑指 Offer 46. 把数字翻译成字符串

题目分析:[[EVD]] - 剑指 Offer 46. 把数字翻译成字符串https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/ 简单描述: 数字对应26个字母下标.计算一个数字有多少种不同的翻译方法。 限制🚫 只翻译成小写字母 示例: 输入: 12258 输出: 5 解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi" 解题思路:

風的博客 114

【AGC005D】~K Perm Counting(计数抽象成图)

注意到位置为id,权值为v ,不合法的情况,当且仅当 v = id+k或 v= id-k。dp(i,j,pd)表示考虑到第i号点, 连了j条边,是否有连接i 到 i-1号点。因此,我们把每一个位置和权值抽象成点 ,不合法的情况之间连一条边,可以构成二分图。由此可知,当选了n条边,就恰好n个位置不合法,限制条件是:连的边不能相邻,求出f(m) ,f(m)指代至少有m个位置不合法的方案数。由此总共有2n 个点 k 条链,链与链之间无边 互不干涉。把二分图展开成k条链,进行dp。简单的乘法原理罢了。

2301_77025310的博客 3952
上一篇: 剑指Offer题解 | #礼物的最大价值# 动态规划(图解)
香芋派丶
博客等级 码龄6年 39粉丝 · 39原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值