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/

相关推荐
可靠的仙人掌3 小时前
SAC(Soft Actor-Critic)算法底座
开发语言·算法·php
海石4 小时前
单调栈复健,顺便,牺牲一下吧,空间复杂度!一切献给AC
算法·leetcode
海石4 小时前
JS击败94%,Hard题想不到动态规划,那就用数组和栈试试
算法·leetcode
杨逢昌工厂6S管理6 小时前
28- 杨逢昌:制造企业仓储6S反复混乱解决方案——四维定置标准化管控体系,让物料混放、通道堵塞等重复性乱象减少90%
大数据·经验分享·笔记·职场和发展·制造·学习方法
alphaTao7 小时前
LeetCode 每日一题 2026/7/6-2026/7/12
算法·leetcode
想吃火锅10057 小时前
【leetcode】56.合并区间js
算法·leetcode·职场和发展
imuliuliang7 小时前
可合并堆在多任务调度中的优势与实现技巧7
算法
学究天人7 小时前
数学公理体系大全:Comprehensive Collection of Mathematical Axiom Systems(卷6)
网络·算法·数学建模·动态规划·几何学·图论·拓扑学
wabs6667 小时前
关于动态规划【力扣72.编辑距离的思考】
算法·leetcode·动态规划
用户333239768847 小时前
我做了一个 RepoMind:让 AI 写架构前,先去看看真实开源项目
算法