【力扣】139:单词拆分 | 动态规划 | BFS | DFS

题目描述

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

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

示例 :
输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-break
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

算法思路

好久没有认真的刷算法题了啊,今天做每日一题认真的写一下。

DFS

这里我的第一思路和这位大佬一模一样的:【手绘图解】三种方法及其优化:DFS、BFS、动态规划,这里偷一下大佬的图。
在这里插入图片描述
算法如下:

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
    	# 先将列表转为集合方便查找
        wordDict=set(wordDict) 
        return self.hel(s,wordDict)
	
	# 使用辅助方法进行DFS| 深度优先搜索
    def hel(self,s,w):
    	# 结束条件:s='' or 遍历完了字符串都没触发递归。
        if not s:return True
        t=''
        for i in range(len(s)):
            t+=s[i]
            if t in w:
                if self.hel(s[i+1:],w):return True
        return False

Python是真的简洁。

且同样死在了一个实例上:

DFS未优化 代码 超时
通过23/36个用例,遇到这种测试用例,超时:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab,
["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]

继续偷大佬的图
在重复计算这里是有点懵逼的,但是仔细想想就能理解,第一次是将单词拆成"a",递归的结果是F,这意味着对递归的任何一个部分来说,如果某个单词拆分出了"a",之后指向的一定是错误的结果……
所以将单词"a"放入一个集合,下次递归前进行判断,如果在集合里就不递归了。

class Solution:
    def wordBreak(self, s: str, wordDict) -> bool:
        wordDict = set(wordDict)
        self.d=set()
        return self.hel(s, wordDict)


    def hel(self, s, w):
        if not s: return True
        t = ''
        for i in range(len(s)):
            t += s[i]
            if t in w:
            ## 更新部分:去除重复计算
                if t not in self.d:
                    if self.hel(s[i + 1:], w): return True
                    else:self.d.add(t)
            ##
        return False

执行用时:48 ms, 在所有 Python3 提交中击败了78.16%的用户
内存消耗:13.9 MB, 在所有 Python3 提交中击败了16.67%的用户

算了今天就写到这,以后填坑。

参考

【手绘图解】三种方法及其优化:DFS、BFS、动态规划

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章