代码
python
# encoding = utf-8
# 开发者:Alen
# 开发时间: 20:18
# "Stay hungry,stay foolish."
class Solution(object):
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: List[str]
:rtype: bool
"""
dp = [False] * (len(s) + 1)
dp[len(s)] = True
for i in range(len(s)-1, -1, -1):
for w in wordDict:
if (i+len(w)) <= len(s) and s[i : i+len(w)] == w:
dp[i] = dp[i+len(w)]
if dp[i]:
break
return dp[0]
解析

核心定义
dp[i] = True 表示 s[i:] (从位置 i 到末尾)可以被字典拆分
目标:求 dp[0],即整个字符串 s[0:] 是否可拆分。
逐行解析
1. 初始化
dp = [False] * (len(s) + 1)
dp[len(s)] = True
```
创建长度为 `n+1` 的数组,全部初始化为 `False`。`dp[len(s)] = True` 是**边界条件**:空串(从末尾之后开始)认为可以拆分。
以 `s = "leetcode"` 为例(长度8):
```
索引: 0 1 2 3 4 5 6 7 8
dp: [F, F, F, F, F, F, F, F, T]
↑ 空串,base case
2. 从右往左遍历
for i in range(len(s) - 1, -1, -1):
i 从 len(s)-1 到 0,即从字符串末尾向开头逐个位置判断。
3. 尝试每个字典单词
for w in wordDict:
if (i + len(w)) <= len(s) and s[i : i + len(w)] == w:
dp[i] = dp[i + len(w)]
对于当前位置 i,尝试每个字典单词 w:
i + len(w) <= len(s):确保从位置i开始放这个词不会越界s[i : i + len(w)] == w:检查从i开始的子串是否恰好等于w- 如果匹配了,那
dp[i] = dp[i + len(w)],意思是:如果匹配了这个词,剩余部分s[i+len(w):]能不能拆分?
4. 提前退出
if dp[i]:
break
```
只要找到一种能拆分的方案,就不用再试其他单词了。
---
## 用例子走一遍
`s = "leetcode"`, `wordDict = ["leet", "code"]`
从右往左填表:
```
i=7: s[7:]="e"
尝试 "leet" → 7+4=11 > 8,越界
尝试 "code" → 7+4=11 > 8,越界
dp[7] = False
i=6: s[6:]="de" → 都匹配不上 → dp[6] = False
i=5: s[5:]="ode" → 都匹配不上 → dp[5] = False
i=4: s[4:]="code"
尝试 "leet" → s[4:8]="code" ≠ "leet"
尝试 "code" → s[4:8]="code" == "code" ✅
dp[4] = dp[4+4] = dp[8] = True ✅
break!
dp[4] = True
i=3: s[3:]="tcode" → 都匹配不上 → dp[3] = False
i=2: s[2:]="etcode" → 都匹配不上 → dp[2] = False
i=1: s[1:]="eetcode"→ 都匹配不上 → dp[1] = False
i=0: s[0:]="leetcode"
尝试 "leet" → s[0:4]="leet" == "leet" ✅
dp[0] = dp[0+4] = dp[4] = True ✅
break!
dp[0] = True
最终 return dp[0] = True。
结果
解题步骤:https://www.bilibili.com/video/BV11nXvBgEMu/
