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

遞歸解法

wordBreak(s, wordDict) 作爲判斷字符串 s 可否拆分爲 wordDict 的函數。則對於字符串 s 和下標 i,若 s[:i+1]wordDict 中,如果 wordBreak(s[i+1:], wordDict) 返回 True,則表示字符串 s 可被拆分爲 wordDict

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        if not s:
            return True
        for i in range(len(s)):
            if s[:i+1] in wordDict and self.wordBreak(s[i+1:],wordDict):
                return True
        return False

遞歸運算可能存在大量的重複計算,當字符串較大時可能會超時。

遞歸+存儲中間值解法

wordMatch 存儲字符串對應函數值。

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        wordMatch,wordSet=dict(),set(wordDict)
        def breakCyc(s):
            if not s:
                return True
            for i in range(len(s)):
                if s[:i+1] in wordSet:
                    flag=wordMatch.get(s[i+1:],-1)
                    if flag==-1:
                        flag=breakCyc(s[i+1:])
                        wordMatch[s[i+1:]]=flag
                    if flag:
                        return True
            return False
        return breakCyc(s)

動態規劃解法

以列表 arr 記錄字符串 s 的每個可拆分前綴的下標,則從上一個前綴繼續拓展遍歷時,若當前的子字符串可拆分,則必然由前面的某一個可拆分前綴和 wordDict 中某個單詞組成。

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        arr,wordSet=[0],set(wordDict)
        for i in range(len(s)):
            for j in arr[::-1]:
                if s[j:i+1] in wordSet:
                    arr.append(i+1)
                    break
        return arr[-1]==len(s)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章