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

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/

相关推荐
星夜离尘5641 分钟前
MATLAB 离散数据分箱:半开区间、末端点与计数、加权和、平均
算法·matlab
Pniubi44 分钟前
力扣76.最小覆盖子串
算法·leetcode·职场和发展
鸿蒙开发爱好者1 小时前
下班后做的小工具和小游戏,我把它们整理成了 WyanHub
网络·人工智能·职场和发展·个人开发
地平线开发者1 小时前
征程6|用 hrt\_model\_exec 看清 YOLOv5x 的输入、原始输出和后处理
人工智能·算法
csdn_aspnet2 小时前
C++ 3个有序点的方向(Orientation of 3 ordered points)
c++·算法
赤生云电竞2 小时前
GPU算力共享平台架构实践:任务分发与资源隔离的关键配置
算法·架构·gpu算力
青少儿编程课堂4 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:折半搜索优化子集枚举(Meet in the Middle)解析
c++·python·算法·bfs·信息学竞赛
Oneshot6 小时前
DLX(Dancing Links)算法详解:求解数独最快的算法
算法
文丑颜不良啊6 小时前
LeetCode2541~2560题目解析
java·leetcode
青少儿编程课堂7 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会Scratch考级:校园连连看解析
c++·python·算法·bfs·信息学竞赛