139. Word Break

25 年 9 月 1 日 星期一
328 字
2 分钟

139. Word Break

Screenshot 2025-09-01 at 3.21.46 pm

原作者

https://leetcode.cn/problems/word-break/solutions/302779/shou-hui-tu-jie-san-chong-fang-fa-dfs-bfs-dong-tai

递归写法

python
class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        n = len(s)
        # i 表示 i 到 n
        @cache
        def dfs(i):
            if i == n:
                return True
            for j in range(i+1, n+1):
                if s[i:j] in wordDict and dfs(j):
                    return True
            return False
        return dfs(0)

为什么递归时最好从大到小递归

递推(动态规划)的逻辑对应

递推中用 f[i] 表示 dfs(i) 的结果(s[i:] 能否被拆分)。 根据递归的依赖关系:f[i] 依赖于 f[j]j > i)。

python
class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        n = len(s)
        # i 表示 (0, i]
        @cache
        def dfs(i):
            if i == -1:
                # 这里返回True
                return True
            # [j, i]
            for j in range(i+1):
                if s[j:i+1] in wordDict and dfs(j-1):
                    return True
            return False
        return dfs(n)
python
class Solution:
    def wordBreak(self, s: str, wordDict: list[str]) -> bool:
        n = len(s)
        word = set(wordDict)
        f = [False] * (n + 1)   # f[i] 表示前缀 s[:i] 能否切分 (i ∈ [0..n])
        f[0] = True             # f[0] = True 代表空串可切分

        # 外层循环:i 表示前缀长度,范围 [1..n]
        for i in range(1, n + 1):
            # 内层循环:j 表示最后一刀的位置,范围 [0..i-1]
            # 切分点:把 s[:i] 拆成 s[:j] + s[j:i]
            for j in range(i):
                # 如果前缀 s[:j] 可切分,且 s[j:i] 在字典中
                if f[j] and s[j:i] in word:
                    f[i] = True
                    break       # 找到一种切分即可,不必继续
        return f[n]             # f[n] 表示整个字符串 s[:n] 能否切分

文章标题:139. Word Break

文章作者:Sirui Chen

文章链接:https://blog.siruichen.me/posts/139_word_break[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。