一.题目描述
一条包含字母 A-Z 的消息通过以下方式进行了编码:
'A' -> 1
'B' -> 2
...
'Z' -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。
示例 1:
输入: "12"
输出: 2
解释: 它可以解码为 "AB"(1 2)或者 "L"(12)。
示例 2:
输入: "226"
输出: 3
解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。
二.思路及代码
动态规划是肯定的
当前的情况也是分为两种,当前s[i]和s[i-1]构成小于26的数字,和将s[i]单独解码,DP[i]=DP[i-1]+DP[i-2]
只不过在求解DP[i]的时候,我是将DP[i-1]的情况逐个列出来看看,还将每个i对应的情况存储,这样的话时间复杂度就成了
O(len(s)*DP[i]),这个DP[i]是非常大的,所以这个方法超时占用的空间又大,这个实现代码如下:
from copy import deepcopy as deepcopy
class Solution:
def numDecodings(self, s: str) -> int:
SL=[[] for i in range(len(s))]
if s[0]!='0':
SL[0].append(deepcopy([deepcopy(s[0])]))
for i in range(1,len(s)):
if SL[i-1]==[]:
break
for sub in SL[i-1]:
if s[i]!='0':
tempsub=deepcopy(sub)
tempsub.append(s[i])
SL[i].append(deepcopy(tempsub))
if int(sub[-1]+s[i])<27:
Temp2=deepcopy(sub)
Temp2[-1]=Temp2[-1]+s[i]
SL[i].append(deepcopy(Temp2))
return len(SL[len(s)-1])
第二种方法是直接求解DP[i],时间复杂度为O[len(s)]
代码如下:
class Solution:
def numDecodings(self, s: str) -> int:
if s[0]=='0':
return 0
DP=[0 for i in range(len(s)+1)]
DP[0],DP[1]=1,1
for i in range(1,len(s)):
if s[i-1]=='0':
if s[i]=='0':
return 0
else:
DP[i+1]=DP[i]
else:
if s[i]=='0':
if int(s[i-1]+s[i])>26:
return 0
else:
DP[i+1]=DP[i-1]
else:
if int(s[i-1]+s[i])>26:
DP[i+1]=DP[i]
else:
DP[i+1]=DP[i]+DP[i-1]
return DP[len(s)]