LeetCode解题之Decode Ways
原题
现在有如下的字母与数字的对应关系:1-A, 2-B, …26-Z。给定一个由数字组成的字符串,判断按照上面的映射可以转换成多少种不同的字符串。
注意点:
- 如果字符不能正常转换,如”70”,那么返回0
例子:
输入: s = “12”
输出: 2(包括”AB”(1 2)和”L”(12))
解题思路
第一感觉就是动态规划,先写了一个从前往后的版本,要复杂的分类要论,代码很乱,后来发现从后开始遍历更加容易。来看一下递推式,假设原先的字符串为”y231”,现在在它之前加一个数字得到”xy231”,如果x不为0,此时,如果”xy”不在1-26之间,那么原先能转换的种类不变,只是在每个字符串之前增加一个x转换后的字母;如果”xy”在1-26之间,那么除了在原先每个字符串之前增加x转换后的字母,还可能是在”231”转化之后的字符串前增加”xy”转化的字母。那如果x等于0呢,此时是一个非法字符串,让它默认为0。但不能跳出循环,因为在前面继续增加数字可能将字符串变为合法的。
AC源码
class Solution(object):
def numDecodings(self, s):
"""
:type s: str
:rtype: int
"""
length = len(s)
if length == 0:
return 0
dp = [0 for __ in range(length + 1)]
dp[length] = 1
dp[length - 1] = 1 if s[length - 1] != '0' else 0
for i in range(length - 2, -1, -1):
if s[i] != '0':
dp[i] = dp[i + 1] + dp[i + 2] if int(s[i:i + 2]) <= 26 else dp[i + 1]
return dp[0]
if __name__ == "__main__":
assert Solution().numDecodings("110") == 1
assert Solution().numDecodings("40") == 0
欢迎查看我的Github (https://github.com/gavinfish/LeetCode-Python) 来获得相关源码。