题目:
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
示例 1:输入: 12258 输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"
提示:0 <= num < 231
解题思路:
根据题意,可总结出递推公式(即转移方程),因此可用动态规划解决:
算法流程:
- 状态定义:设动态规划列表dp,dp[i]代表以x(i)为结尾数字的翻译方案数量;
- 转移方程:若x(i)和x(i-1)组成的两位数字可以被翻译,则dp[i]=dp[i-1]+dp[i-2],否则dp[i]=dp[i-1];
- 初始状态:dp[0]=dp[1]=1,即'无数字'和‘第1位数字’的翻译方法数量均为1;
- 返回值: dp[n],即此数字的翻译方案数量。
当 numnum 第1, 2 位的组成的数字∈[10,25] 时,显然应有 2 种翻译方法,即 dp[2] = dp[1] + dp[0] = 2,而显然dp[1] = 1 ,因此推出dp[0] = 1。
通过字符串切片s[i - 2:i] 获取数字组合10x(i-1)+x(i),通过对比字符串 ASCII 码判断字符串对应的数字区间。
代码:
class Solution:
def translateNum(self, num: int) -> int:
s = str(num)
a = b = 1
for i in range(len(s) - 2, -1, -1):
a, b = (a + b if "10" <= s[i:i + 2] <= "25" else a), a
return a
复杂度:
- 时间复杂度:O(N),N为字符串s的长度(即数字nun的位数log(num)),其决定了循环次数;
- 空间复杂度:O(N),字符串s使用O(N)大小的额外空间。