LeetCode 面试题46. 把数字翻译成字符串 | Python

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


题目来源:力扣(LeetCode)https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof

题目


给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。

示例 1:

输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"

提示:

  • 0 <= num < 231

解题思路


思路:动态规划

先理清题意,题目中说明规则: 0 翻译成 "a", 1 翻译成 "b",...,25 翻译成 "z"。而且题目中也说明【一个数字可能有多个翻译】。那么这里就可以想到,当数字大于等于 10 小于等于 25 的时候,这部分的数字可以看出是两个单独数字组成,或者单独当成一个数字。

现在看示例 1:

输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"

看下面的解释中,我们可以看到:

  • "bccfi" 这种情况就是将所有的数字单独翻译,即是 [1, 2 ,2, 5, 8]
  • 剩下的 4 个就是连续两位数字可考虑组合的情况
    • [1, 22, 5, 8] 对应翻译的是 "bwfi"
    • [1, 2, 25, 8] 对应翻译的是 "bczi"
    • [12, 2, 5, 8] 对应翻译的是 "mcfi"
    • [12, 25, 8] 对应翻译的是 "mzi"

在上面的示例中,'58' 这个组合是不成立的,我们知道组合的数字的范围应该落在 [10, 25] 之间。

那么也就是说,翻译的规则,在字符串的第 i 个位置中可以分为两种情况:

  • 单独进行翻译
  • 如果与 i - 1 位能够组合成数字且落在 [10, 25],那么可以连起来翻译。

现在假设将题目给出的数字 num 第 i 个数字记为 x_i,例如示例中的 num = 12258,那么 x_1 就是 1。

现在定义动态规划列表 dp,假设 dp[i] 为 x_i 结尾的数字的翻译方案。

按照前面得出的翻译规则总结出转移方程。

x_{i-1}x_i 两个数字组合可被翻译时,这里就会有两种情况。单独翻译,或者组合翻译。也就是:

  • 当组合翻译的时候,x_{i-1}x_i 组合确定,前面 i-2 个数的翻译方案为 dp[i-2]。
  • 当单独翻译的时候,x_i 确定,前面 i-1 个数的翻译方案为 dp[i-1]。
  • 也就是说当 x_{i-1}x_i 两个数字组合可被翻译的时候,可由上述两种情况结合,最终 dp[i] = dp[i-2] + dp[i-1]。

如果 x_{i-1}x_i 两个数字无法组合,那么就只能当成单个数字进行翻译。所以 dp[i] = dp[i-1]。

这里需要注意的可组合数字落在的区间是 [10, 25],前面已经说明了,只有这种情况才能够成功组合被翻译。

还有一种情况,就是 x_{i-1} 为 0 的时候,这种情况可以会出现 00, 01, 02, ... 这样的组合数字。但是这种情况是不能够被翻译的。

所以最终的状态转移方程,以及具体落在的区间:

dp[i] = \begin{cases} dp[i-2] + dp[i-1], & 10x_{i-1} + x_i \in [10, 25] \\ dp[i-1] & 10x_{i-1} + x_i \in [0, 10) \bigcup (25, 99] \end{cases}

注意,这里我们并不考虑三位数的组合

在这里,dp[i] 表示的是以 x_i 结尾的数字的翻译方案。当 i=0 和 i=1 的时候,表示的是【无数字】和【第一个数字】。这里都初始化为 1。(前面说明了 x_1 表示的是第 1 个数字,如题目 12258 中的第一个数字 1。)

反向推导 dp[0] 的值,假设当出现两个数字能够组合且被翻译的情况下,例如 12,那么 dp[2] 显然是等于 2。要么以 [1, 2] 的形式,要么以 [12] 的形式进行翻译。
此时 dp[2] = dp[1] + dp[0] = 2,而 dp[1] 为 1,那么 dp[0] = 1。

而最终我们需要求得的结果就是 dp[n],也就是题目中所需求的翻译方案(n 表示的是数字长度。)

在这里可以使用字符串截取的方法去实现,这里需要将数字下转换为字符串,缺点是字符串会占用一定的空间。这里采用字符串截取的方法来求解。还有一种方法是使用取模的方法(可考虑尝试)

具体的代码如下。

代码实现


class Solution:
    def translateNum(self, num: int) -> int:
        string = str(num)
        n = len(string)

        dp = [0] * (n+1)
        
        dp[0]=1
        dp[1]=1

        for i in range(2, n + 1):
            if "10" <= string[i-2:i] <="25":
                dp[i] = dp[i-1] + dp[i-2]
            else:
                dp[i] = dp[i-1]
        
        return dp[n]

实现结果


实现结果

总结


  • 本题使用的动态规划,先分析题意,找出翻译的规则。可以发现,当第 i 个数字被翻译的时候,可能出现两种情况:
    • 单独翻译第 i 个位置的数字
    • 当第 i 个位置的数字与第 i-1 位置的数字组合且可被翻译,那么可考虑组合进行翻译
  • 根据上面的翻译规则,可以求得转移方程(具体参考上面的解析):
    • 当两个连续数字能够组合的情况下:dp[i] = dp[i-2]+dp[i-1]
    • 否则:dp[i]=dp[i-1]
  • 对动态规划列表进行初始化,确定最终求解的值为 dp[n]。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351