139. 单词拆分 - 力扣(LeetCode)

代码

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):

ilen(s)-10,即从字符串末尾向开头逐个位置判断。

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/

相关推荐
JieE2125 小时前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
JieE2121 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack201 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树2 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2122 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2122 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术2 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦2 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
用户497863050733 天前
(一)小红的数组操作
算法·编程语言