返回
巧解「力扣」639 题:化繁为简,解码无忧
人工智能
2023-09-15 07:45:57
「力扣」639 题简介
「力扣」第 639 题要求你计算一个字符串中不同解码方法的数量。字符串由数字组成,每个数字可以解码成对应的英文字母。例如,"1" 可以解码为 "a","2" 可以解码为 "b",以此类推。
但本题有一个额外的复杂性:字符串中可能包含通配符 '*'。通配符可以表示任何一个数字,因此它可以扩展解码的可能性。
化繁为简的解题思路
乍一看,这道题似乎非常复杂,但实际上,我们可以通过一个巧妙的思路将其化繁为简。
首先,我们将字符串分成两个部分:无通配符部分 和通配符部分 。对于无通配符部分,我们可以直接应用「力扣」第 90 题的解法。
「力扣」90 题回顾
在「力扣」第 90 题中,我们定义了一个动态规划数组 dp
。dp[i]
表示字符串的前 i
个字符的解码方法数量。我们可以使用以下公式来更新 dp
数组:
dp[i] = dp[i-1] + dp[i-2]
其中,dp[i-1]
表示前 i-1
个字符的解码方法数量,dp[i-2]
表示前 i-2
个字符的解码方法数量。
通配符部分的处理
对于通配符部分,我们可以将其分为两种情况:
- 通配符单独出现: 在这种情况下,通配符可以表示任何一个数字,因此它可以扩展为 9 种解码方法('a' 到 'i')。
- 通配符与数字一起出现: 在这种情况下,通配符可以表示任何一个数字,但它必须与前面的数字一起解码。例如,"2*" 可以解码为 "ab"、"ac"、"ad" 等。
完整解法
综上所述,我们可以得到以下完整的解法:
- 定义动态规划数组
dp
。 - 对于无通配符部分,直接应用「力扣」第 90 题的解法。
- 对于通配符部分,根据通配符的出现情况进行处理。
- 将无通配符部分和通配符部分的解码方法数量相乘,得到最终结果。
代码示例
def numDecodings(s: str) -> int:
# 初始化动态规划数组
dp = [0] * (len(s) + 1)
# 无通配符部分的解码方法数量
dp[0] = 1
if s[0] != '*':
dp[1] = 1
# 遍历字符串
for i in range(2, len(s) + 1):
if s[i-1] != '*':
dp[i] += dp[i-1]
if s[i-2] != '*' and (s[i-2] == '1' or (s[i-2] == '2' and s[i-1] <= '6')):
dp[i] += dp[i-2]
if s[i-1] == '*':
dp[i] += 9 * dp[i-1]
if s[i-2] == '*' and s[i-1] == '*':
dp[i] += 15 * dp[i-2]
if s[i-3] == '1':
dp[i] += 9 * dp[i-3]
elif s[i-3] == '2' and s[i-1] <= '6':
dp[i] += 6 * dp[i-3]
# 返回最终结果
return dp[len(s)]
总结
通过将字符串分成无通配符部分和通配符部分,并巧妙地处理通配符的情况,我们可以将「力扣」第 639 题这道困难的解码难题化繁为简。希望本文提供的解题思路能帮助你轻松破解这道难题!