LeetCode139-单词拆分

人生路上总有很多遗憾

每个人都会这么安慰着自己

但当我碰到这样的遗憾时

我肯定要豁出一切去尝试弥补这样的遗憾

哪怕受人嘲讽!!!


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

思路:

本题我也采用了两种方法,即回溯法和动态规划法,但效果天差地别。

方法一 回溯法:

关于回溯法我之前写了一篇文章专门介绍,各位读者可以看看,里面我详细介绍了回溯法的求解步骤,相信会对大家有所出发。

https://blog.csdn.net/weixin_36431280/article/details/84891567

于本题而言,无非就是从给定字符串s的第一个字符开始遍历,如果截取的子串刚好出现在wordDict中,那么接着该子串的位置继续往后遍历,重复同样操作,如果最后字符串s分割成的几个子串刚好都出现在wordDict中,那么输出True,反之输出False。这也就是回溯的思想,其实很easy!

代码如下:

class Solution(object):
    # 回溯法
    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: List[str]
        :rtype: bool
        """
        def back(start=0, flag=False):
            if start >= len(s):
                return True
            for end in range(start, len(s)):
                sub_str = s[start:end+1]
                if sub_str in wordDict:
                    flag = back(end+1)
                    if flag is True:
                        return True
            return False
        return back()


if __name__ == "__main__":
    s = "aaaaaaa"
    wordDict = ["aaaa","aaa"]
    flag = Solution().wordBreak(s, wordDict)
    print(flag)

但是超出时间限制了啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!气死我了,没办法,效率不行,只能是试试动态回归算法了。

方法二:动态规划法

说到动态回归,我之前也写了一篇文章来专门介绍动态回归算法的求解步骤,大家也可以看看找找灵感。

https://blog.csdn.net/weixin_36431280/article/details/86616672

大致思路就是:

定义一个标记列表flag,flag[i]表示到第i-1个字符时,是否为能被拆分为字典里的单词

状态转移矩阵:

flag[j] = flag[i] and s[i:j+1] in wordDict

代码如下:

class Solution(object):
    # 本题回溯法超出时间限制,采用动态回归法
    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: List[str]
        :rtype: bool
        """
        # 初始化标记列表
        flag = [True]+[False]*len(s)

        for start in range(len(s)):
            if flag[start]:
                for end in range(start+1, len(s)+1):
                    if s[start:end] in wordDict:
                        flag[end] = True
        return flag[-1]


if __name__ == "__main__":
    s = "aaaaaaa"
    wordDict = ["aaaa","aaa"]
    flag = Solution().wordBreak(s, wordDict)
    print(flag)

执行效率中等吧,在70%左右。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习的学习者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值