题目描述
思路解析动画文字版
关键不是背模板,而是看懂为什么这题适合动态规划 · 字符串。
1. 初始化 dp[0]=dp[1]=1:dp[i] 表示「前 i 个字符」有多少种解码法。先填 dp[0]=1、dp[1]=1。
2. 算 dp[2]:末 1 位 '2' 单独解码:每个 dp[i] 有两条来路。先看末 1 位 '2':在 1~9 能单独成字母(2→B)→ 继承 dp[1]。
3. 末 2 位 '22' 合并解码 → dp[2]=2:再看末 2 位 '22'=22(在 10~26,对应 V)→ 也能合并解码 → 加 dp[0]。两条来路相加 dp[2]=2。
4. 算 dp[3]:末 1 位 '6' 单独解码:轮到 dp[3]。末 1 位 '6' 在 1~9 → 继承 dp[2]=2。
5. 末 2 位 '26' 合并 → dp[3]=3:末 2 位 '26'=26(恰在 10~26,对应 Z)→ 再加 dp[1]=1 → dp[3]=3。
6. 关键帧 · 两条来路 + 答案:关键帧:每位都有「末 1 位单独(1~9)」和「末 2 位合并(10~26)」两条来路,方案数相加。"226" 的 3 种:2·2·6、22·6、2·26。
把这句话记住,下次遇到同类题,就能更快选出方向。
边界三连:边界三连:极端输入先过一遍。
几个高频追问,记住答法。
参考代码
class Solution: def numDecodings(self, s): if not s or s[0] == "0": return 0 n = len(s) dp = [0] * (n + 1) dp[0] = dp[1] = 1 for i in range(2, n + 1): if s[i - 1] != "0": # 末1位 1~9 可单独 dp[i] += dp[i - 1] two = int(s[i - 2:i]) if 10 <= two <= 26: # 末2位 10~26 可合并 dp[i] += dp[i - 2] return dp[n]复杂度
- 时间复杂度:O(n),扫一遍字符串,每位 O(1) 转移
- 空间复杂度:O(n),dp 数组 O(n),只用前两项可滚动到 O(1)
可套用的代码模板
模板不是死背,而是提醒你写代码前先把状态、转移和边界排好。
Python
# 解码方法骨架 · 带约束的爬楼梯dp[0] = dp[1] = 1for i in range(2, n+1): if s[i-1] != "0": # 末1位 1~9 可单独解码 dp[i] += dp[i-1] if 10 <= int(s[i-2:i]) <= 26: # 末2位 10~26 可合并 dp[i] += dp[i-2]return dp[n]易错点
面试追问把动画讲成自己的话
追问为什么像爬楼梯但更难?
追问0 怎么处理?
追问复杂度?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
零钱兑换
LeetCode 322 · 中等 · 沿着 一维动态规划 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题