题目
一条包含字母 A-Z 的消息通过以下映射进行了 编码 :
‘A’ -> 1
‘B’ -> 2
…
‘Z’ -> 26
要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,“111” 可以将 “1” 中的每个 “1” 映射为 “A” ,从而得到 “AAA” ,或者可以将 “11” 和 “1”(分别为 “K” 和 “A” )映射为 “KA” 。注意,“06” 不能映射为 “F” ,因为 “6” 和 “06” 不同。
给你一个只含数字的 非空 字符串 num ,请计算并返回 解码 方法的 总数 。
题目数据保证答案肯定是一个 32 位 的整数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/decode-ways
一、动态规划解析
2 ->2 -> 1
22->2 2, 22 -> 2
222 -> 2 2 2, 22 2, 2 22,->3
2223 -> 2 2 2 3, 22 2 3, 2 22 3, 2 2 23, 22 23 ->5
# if 倒一和倒二能组成最后一个 dp[i] = dp[i-1] + dp[i-2]
2265 - > 2 2 6 5, 22 6 5, 2 26 5 ->3
# if 倒二和倒一组不成最后一个 dp[i] = dp[i-1]
220 -> 2 20 -> 1
# if 有0并且能够组成一个数dp[i] = dp[i-2]
2605 ->0
# if 中间有0并且不能与前面组成一个数 0
二、代码
def numDecodings(self, s: str) -> int:
if s[0] == '0': return 0
dp=[1,1]
for i in range(2, len(s) + 1):
if (s[i - 2: i ] > '10' and s[i - 2: i] <= '26') and s[i - 1] != '0':
dp.append(dp[i - 1] + dp[i - 2])
elif s[i - 1] != '0':
dp.append(dp[i - 1])
elif s[i - 2: i] == '10' or s[i - 2: i] == '20':
dp.append(dp[i - 2])
else:
return 0
return dp[len(s)]