139. 单词拆分

6 篇文章 0 订阅
2 篇文章 0 订阅

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

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

这题我一开始用暴力的回溯解法,因为忘记记录已搜索过的拆分点,导致在极端数据下会超时,时间复杂度会到O(n^n),如下:
在这里插入图片描述
因此,改用题解中的第一种解法记忆化回溯,也就是用一个列表记录已经访问过的拆分点,代表从[x,n)是否true,这样就能将时间复杂度转化为O(n^2),代码如下:

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        n = len(s)
        if n == 0 or (n == 1 and s in wordDict):
            return True
        if n == 1:
            return False

        dic = {}
        for word in wordDict:
            p = s.find(word)
            while p != -1:
                if p not in dic.keys():
                    dic[p] = []
                dic[p].append(p+len(word))
                p = s.find(word, p+1)

        visited = [False for _ in range(n)]
        ans = [False for _ in range(n)]

        def findBreak(x):
            if x == n:
                return True
            if visited[x]:
                return ans[x]

            if x not in dic.keys():
                visited[x] = True
                return False
            for y in dic[x]:
                ans[x] = findBreak(y)
                if ans[x]:
                    break
            visited[x] = True
            return ans[x]

        return findBreak(0)

另外,题解还介绍了两种跟记忆化回溯时间空间复杂度相似的解法
① 宽度优先搜索,在s前后假定一个begin和end,然后不断从字典里搜索符合与当前子串开头相同且能匹配的单词;
② 动态规划:思想还是通过dp[x]记录[0,x)是否能够满足条件,然后用状态转移方程解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值