再谈斐波那契,把数字翻译成字符串

  • 题目描述
  • 算法分析
    • python代码

  学习的过程就是用记忆构建一个知识网的过程,网的密度决定了你容易遗忘的程度。如果担心遗忘,就努力把这个知识的网构建的更密一些。在讲算法设置的大致流程的时候,我通过斐波那契数列讲解了一下算法求解优化的大致过程。从斐波那契数列讲解算法设计的思路这篇文章写得还是蛮精彩的,感兴趣的可以回过去看看。
  本文将继续遵循那篇文章的讲解再来谈一个比较有趣的算法题目。

题目描述

  给定一个数字,我们按照如下规则把它翻译为字符串,0翻译成"a",1翻译成"b"…25翻译成"z",根据字符的字母顺序对应数字。给定一个数字串,可能会翻译成多个字符串。例如,12258有5种不同的翻译,分别是"bccfi",“bwfi”,“bczi”,“mcfi"和"mzi”。请编程实现一个函数,用来计算一个数字有多少种不同的翻译。

算法分析

  接触到这个题目,我们先来做分析。如果直接给你一个很长很长的数,那肯定都不会分析了。所以先想想如何把问题化简。以题目中给出的12258为例,第一个数字是1,显然是1的话就会存在两种情况,第一种情况,1单独翻译。第二种情况,因为1可以和后面的数字合并起来翻译,这个很容易理解,只要和后面的数字合并起来小于26,都可以在单独翻译的基础上,多一种合并翻译。我们先看1单独翻译,那么后面我们就要求2258的翻译情况,如果我们把1和后面的2合并翻译,那么后面就要求258的翻译情况。
  这个问题也可以从后往前分析,因为性质是一样的,但是我觉得从前往后更容易理解。
  这个时候我们把问题规模缩小了,问题还是求数字的翻译情况,类型没有变。这个过程很适合用递归来实现。此时我们总结一下,这个化简问题的过程。如果当前数字可以和后面的数字合并翻译,那我们就会产生两个递归分支,我们的总数目就是两个递归分支数目的和。如果不能合并翻译,那么总数目就直接是后面数字的翻译数目。
  但是我们不能光分析出递归就停止,因为递归的算法一定要有终止条件,显然这个题目中的终止条件就是翻译完了最后一个字符,也就是说两个数字翻译出一个字符,和一个数字翻译出一个字符。所以写代码的时候剩余两个数字就可以停止了,如果可以合并,返回2,如果不能合并翻译返回1。
  但是如果我们继续分析,就会发现我们第一步把问题转换成了求2258的翻译数目,如果进一步化简问题,我们就需要求258的翻译数目,这个问题好像就是我们第一次分解求的第二个问题,这就涉及到我上篇文章中所写的,就是递归带来重复计算的问题,我们可以通过添加备忘录,来解决重复计算的问题。如果我们不对题目有过高的要求,到这里已经可以停止了,毕竟递归写出来的代码简单,而且这样的话避免了重复计算,复杂度不会高。
  但是,根据我们之前学到的算法分析套路,我们不能就此收手,我们还可以对递归继续优化。我们之前已经说过终止条件,就是一个字符,那么显然这就是我们所能解决的基础问题,递归是自顶向下的算法,我们能否通过自底向上的算法,动态规划来解决递归栈的调用问题,我们从我们所能解决的基础问题入手,那就是一个字符(可能是一个数字,可能是两个数字)。显然这个时候就是逆向思维,我们扫描到第iii个数字(i>2i>2i>2),它有可能无法和前面的数字合并,到这个数字为止,翻译数目就是前面数字的翻译数目f(i)=f(i−1)f(i)=f(i-1)f(i)=f(i−1)。但是如果可以和前面的数字合并,那么可以单独翻译,此时的翻译数目就是f(i)f(i)f(i),可以合并翻译,翻译数目就是f(i−2)f(i-2)f(i−2),所以总的翻译数目就是f(i−1)+f(i−2)f(i-1)+f(i-2)f(i−1)+f(i−2)。
  我们可以对上面的分析总结一下,通过指示函数I(x)∈0,1I(x)\in{0,1}I(x)∈0,1来表示第x个字符是否可以和前面的字符合并翻译,则我们轻易推出公式,截止第x个字符,可翻译的数目f(x)=f(x−1)+I(x)f(x−2),x>2f(x)=f(x-1)+I(x)f(x-2), x>2f(x)=f(x−1)+I(x)f(x−2),x>2,通过这种分析,就很容易写出动态规划状态转移方程了。可能很多人写出这个转移方程才恍然大悟,这个怎么这么像斐波那契数列的递推式,这个问题比较简单,如果大家能轻易看出来这就是有条件的斐波那契数列,也可以直接写出代码。

python代码

def getTranslationsCount(num):# 未对异常输入做出处理if isinstance(num,int):num=str(num)f0=0f1=1for i in range(len(num)):if num[i-1]=='1' or num[i-1]=='2' and num[i]<'6': # 判断是否可以和前面的数字合并f=f0+f1else:f=f1f0=f1f1=freturn f

  这个代码的复杂度分析很简单了,当然最后的代码实现了空间复杂度O(1)O(1)O(1),时间复杂度O(n)O(n)O(n),至于其他分析的复杂度也在我的链接文章中详细讲解过,这里不重复赘述。
  这是一个很简单的问题,在这里的讲解主要是为了巩固文章开头链接的文章,同时也为了向大家展示一种斐波那契数列的变体问题,问题大家就当见过就行。问题分析的步骤大家应当了熟于心,对问题养成直觉之后便可脱离套路。

再谈斐波那契,把数字翻译成字符串相关推荐

  1. 把数字翻译成字符串/斐波那契数列/青蛙跳台阶

      今天做到剑指Offer中面试题46:把数字翻译成字符串,一看,这不是之前的斐波那契数列和青蛙跳台阶的翻版吗?遂记录一下解题思路. 题目:给定一个数字,我们按照如下规则把它翻译为字符串: 0 0 0 ...

  2. 剑指Offer46——把数字翻译成字符串

    [写在前面]:这道题并不难,但看到题解,发现,自己的代码略显笨拙啊,优秀大佬解题真的高,代码清晰明了,纪念一下差距感(自己递归,回溯还有待加强训练) 原题链接: 剑指 Offer 46. 把数字翻译成 ...

  3. leetcode 题库46. 把数字翻译成字符串

    面试题46. 把数字翻译成字符串 给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 "a" ,1 翻译成 "b",--,11 翻译成 "l& ...

  4. leetcode面试题46. 把数字翻译成字符串

    leetcode面试题46. 把数字翻译成字符串 给定一个数字,我们按照如下规则把它翻译为字符串:**0 翻译成 "a" ,1 翻译成 "b",--,11 翻译 ...

  5. 【LeetCode】剑指 Offer 46. 把数字翻译成字符串

    [LeetCode]剑指 Offer 46. 把数字翻译成字符串 文章目录 [LeetCode]剑指 Offer 46. 把数字翻译成字符串 package offer;public class So ...

  6. 【算法】剑指 Offer 46. 把数字翻译成字符串

    1.概述 剑指 Offer 46. 把数字翻译成字符串 给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 "a" ,1 翻译成 "b",--,11 翻 ...

  7. 剑指 Offer 46. 把数字翻译成字符串(动态规划+回溯+递归 解法)

    剑指 Offer 46. 把数字翻译成字符串 问题描述 给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 "a" ,1 翻译成 "b",--,11 翻 ...

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

    剑指 Offer 46. 把数字翻译成字符串 给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 "a" ,1 翻译成 "b",--,11 翻译成 &q ...

  9. 【剑指Offer】个人学习笔记_46_把数字翻译成字符串

    目录 题目: [剑指 Offer 46. 把数字翻译成字符串](https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan- ...

  10. leetcode 剑指offer-46.把数字翻译成字符串

    原题如下: 剑指offer-46.把数字翻译成字符串 2020年6月9日 每日一题 题解 方法一: 当我们考虑单个数字的时候,就只有一种翻译的结果,重要的是,我们遇到连续两个字母也可以翻译成字母,那么 ...

最新文章

  1. 在CentOS 6.3 64bit上安装MySQL for python模块
  2. matlab小技巧与verilog小技巧
  3. SAP CRM里business partner在订单处理中的determination流程
  4. SVN trunk branch tags 区别
  5. element table多选表格_【经验总结】vue + element-ui 踩坑—— table 篇
  6. php memcache 有效期,PHP可以拿到memcache中的key的过期时间吗?
  7. java基础 内部类详解
  8. 如何将mp4视频转换成flv格式
  9. nomogram,列线图,因素
  10. python将pdf转图片_利用Python将pdf转为图片
  11. 01-探寻 JavaScript 反爬虫的根本原因
  12. 第一章,实现数据完整性
  13. 【单调队列】51nod 1275 连续子段的差异
  14. 电脑怎么录屏幕视频带声音?电脑录屏教程介绍
  15. java 遍历出d盘所有文件_JAVA遍历一个文件夹中的所有文件
  16. 新酒店图集 | 北京大兴希尔顿、昆明喜来登和昆明德尔塔、银川JW万豪与银川万怡双品牌酒店陆续开业...
  17. ChatGPT会对未来5年的NLP算法从业者带来怎样的冲击?
  18. JavaScript-HTML中的JavaScript
  19. 机器人测钢卷直径_机器人热轧钢卷喷号漆
  20. IoT高级设备检索——设备管理运维类

热门文章

  1. 短途游成了携程、美团、抖音眼中的“香饽饽”?
  2. 参考文献中英文人名_参考文献英文人名的缩写规则
  3. 《SteamVR2.2.0开发指南》(Yanlz+Unity+XR+SteamVR+OpenXR+OpenVR+Valve+VIVE+Oculus+Interaction+VR+立钻哥哥++ok++)
  4. 数据库系统是由那些组成的?
  5. java毕业设计培训学校教学管理平台源码+lw文档+mybatis+系统+mysql数据库+调试
  6. 四川省巴中市谷歌高清卫星地图下载
  7. Linux下实现双机互信
  8. 测试手机软件打开速度的app,一加6千分之一秒 百款APP打开速度对比
  9. JavaEE程序猿面向对象世界观⑥
  10. SDU程序设计思维Week5-作业 B-TT's Magic Cat