【力扣】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、動態規劃

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