leetcode面试题46. 把数字翻译成字符串(Python实现)

题目:把数字翻译成字符串
来源:Leetcode
leetcode面试题46. 把数字翻译成字符串(Python实现)_第1张图片

动态规划

经典的动态规划题目,以输入12258 为例,我们可以看到,之所以会有多种方法翻译是因为 1 可以被映射到字母 a ,而 12 同样也可以在映射表中找到对应的映射关系。
但是注意,以 0 开头的数字是无效的,例如 10020 中的 02 并不是一个有效的映射,因此这种情况我们不必要考虑。

12258 为例,我们分别对其编号X1X2X3X4X5 (即Xi), (1 <= i <= 5)
那么现在,Xi 处的翻译情况分如下两种情形:

  1. 我们对 Xi 单独编号,则此时有 f(Xi) = f(Xi-1), 这是显而易见的,因为若我们只对单独一位编号,那么无论增加多少位,翻译方案都是不变的。
  2. 我们对 Xi-1Xi 整体进行编号,那么此时 f(Xi) = f(Xi-2) + f(Xi-1),思想同 步骤1,因为若对 Xi-1Xi 整体编号,那么由步骤1可以得知,此时 f(Xi) = f(Xi-2),在加上此时我们还可以单独对 Xi 编号,所以还要加上 f(Xi-1) 的情况。但是,但我们考虑二位一起编号时,对数的范围是由要求的(为什么不考虑三位,显然映射的范围是 0 <= x <= 25,任何一个三位数都是不可能满足这个范围的),那么这个两位数的范围是多少呢? 应该是 10<= x <= 25, 为什么从 10 开始,因为我们之前说过,两位数是不可以出现 诸如 01~09 这些情况的,映射表里面也是没有这些的。

因此,我们已经有了状态转移方程,此时我们只需构造一个DP数组,就可以自底向上的求出解了。但是考虑到我们实际上只关心X-1X-2位置的翻译方案数,因此我们可以只用两个变量保存即可,而不必保存整个数组,这也是动态规划中常用的滚动数组思想来压缩空间。代码如下:

class Solution:
    def translateNum(self, num: int) -> int:
        s = str(num)
        a = b = 1
        for i in range(1, len(s)):
            if '10' <= s[i-1:i+1] <= '25':
                a, b = b, a+b
            else:
                a = b
        return b

时间复杂度:O(n),只遍历一遍输入
空间复杂度:O(n),因为需要额外 字符串 s来保存输入数

你可能感兴趣的:(算法,python)