给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
示例 1:
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", “bwfi”, “bczi”,“mcfi"和"mzi”
方法:动态规划
首先将输入数字转化为字符串,s = str(num)
。
- 状态定义: d p [ i ] dp[i] dp[i]表示截取到字符串中第 i i i个数时,共有 d p [ i ] dp[i] dp[i]种翻译方法。
- 状态转移方程: 若字符串中第 i − 1 i-1 i−1个数和第 i i i个数 s [ i − 1 ] s[i-1] s[i−1]与 s [ i ] s[i] s[i]组合后可以被翻译成一个字母时, d p [ i ] = d p [ i − 1 ] + d p [ i − 2 ] dp[i] = dp[i-1] + dp[i-2] dp[i]=dp[i−1]+dp[i−2]; 否则 d p [ i ] = d p [ i − 1 ] dp[i] = dp[i-1] dp[i]=dp[i−1]
此时需要考虑的是第 i − 1 i-1 i−1 个数和第 i i i 个数组成什么样的两位数后可以被翻译呢?
能被翻译的两位数范围一定是10 ~ 25,因为25对应的是最后一个字母 ‘z’;其次如果是0开头的,00 ~ 09也不行
- 初始状态: d p [ 0 ] = 1 dp[0] = 1 dp[0]=1,当 s [ 0 ] s[0] s[0]和 s [ 1 ] s[1] s[1]组合后可以被翻译时 d p [ 1 ] = 2 dp[1] = 2 dp[1]=2,否则 d p [ 1 ] = 1 dp[1] = 1 dp[1]=1
- 返回值: d p [ ] dp[] dp[]数组最后一个数
Python代码
class Solution:
def translateNum(self, num: int) -> int:
s = str(num)
l = len(s)
dp = [1]*l
if l == 1: return 1
if '10'<= s[0:2] < '26': dp[1] = 2 #一定是大于等于10,而不是大于9,注意字符串比较大小的规则
for i in range(2, l):
if '10' <= s[i-1: i+1] < '26':
dp[i] = dp[i-1] + dp[i-2]
else: dp[i] = dp[i-1]
return dp[-1]
需要注意: 取范围10 ~ 25时的左边界一定是'10'<=
而不能是'9'<
,因为在字符串是按位比较的,因此“19”小于“9”。