leetcode-139. 单词拆分

题目

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

说明:

拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。

示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。

示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
     注意你可以重复使用字典中的单词。

示例 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

解题思路

DP

Use dp[i][j] to denote whether the s[i:j+1] could be found in wordDict, the transform equation would be:
d p [ i ] [ j ] = s [ i : j + 1 ]  in wordDict    ∪    ( d p [ i ] [ k ] ∩ d p [ k + 1 ] [ j ] ) , ∀ i < = k < j dp[i][j] = s[i:j+1] \text{ in wordDict} \; \cup \; (dp[i][k] \cap dp[k+1][j]) , \forall i <= k < j dp[i][j]=s[i:j+1] in wordDict(dp[i][k]dp[k+1][j]),i<=k<j
We would only use the upper triangle of the matrix, and since we have to iterate all the columns at each position, the time complexity would be c o l 2 ∗ r o w {col}^2 * row col2row
Time complexity: o ( n 3 ) o(n^3) o(n3) where n = len(s)
Space complexity: o ( n 2 ) o(n^2) o(n2)

Reduced DP

Since we only use upper triangle of the matrix, it’s actually could be reduced from a matrix to list. Use dp[i] to denote that whether s[:i] could be segmented and included in wordDict, then the transform equation would be:
d p [ i ] = d p [ k ] ∩ ( s [ k : i ]  in wordDict ) , ∀    0 ≤ k < i dp[i] = dp[k] \cap (s[k:i] \text{ in wordDict}), \forall \;0\leq k < i dp[i]=dp[k](s[k:i] in wordDict),0k<i
Note that dp[i] doesn’t include s[i], we may need to add an initial value for s[0].

Time complexity: o ( n 2 ) o(n^2) o(n2)
Space complexity: o ( n ) o(n) o(n)

代码

DP

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        n = len(s)
        dp = [[False] * n for _ in range(n)]
        # initialize
        for i in range(n):
            if s[i] in wordDict:
                dp[i][i] = True
        for i in range(n - 2, -1, -1):
            for j in range(i + 1, n):
                for k in range(i, j):
                    dp[i][j] |= dp[i][k] & dp[k + 1][j]
                dp[i][j] |= s[i:j + 1] in wordDict
        return dp[0][n - 1]

Reduced DP

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        dp = [True] + [False] * len(s)
        for i in range(1, len(s) + 1):
            for k in range(i):
                dp[i] |= dp[k] & (s[k:i] in wordDict)
        return dp[len(s)]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值