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/

相关推荐
aaaameliaaa3 小时前
字符函数和字符串函数
c语言·笔记·算法
城管不管4 小时前
ReAct、Plan-and-Execute、Reflection 三大智能 Agent 范式核心区别
java·人工智能·算法·spring·ai·动态规划
月疯4 小时前
二分法算法(水平等分图形面积)
算法
豆瓣鸡4 小时前
算法日记 - Day3
java·开发语言·算法
白白白小纯5 小时前
算法篇—反转链表
c语言·数据结构·算法·leetcode
Achou.Wang5 小时前
深入理解go语言-第5章 并发编程——Go的灵魂
大数据·算法·golang
The Chosen One9855 小时前
高进度算法模板速记(待完善)
java·前端·算法
圣保罗的大教堂7 小时前
leetcode 3517. 最小回文排列 I 中等
leetcode
土豆.exe8 小时前
Fastjson2 2.0.53 哈希碰撞 RCE:从原理到三种打法
算法·哈希算法
黄河123长江8 小时前
有限Abel群的结构()
算法