难度: Hard
原题连接
内容描述
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences.
Note:
The same word in the dictionary may be reused multiple times in the segmentation.
You may assume the dictionary does not contain duplicate words.
Example 1:
Input:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
Output:
[
"cats and dog",
"cat sand dog"
]
Example 2:
Input:
s = "pineapplepenapple"
wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
Output:
[
"pine apple pen apple",
"pineapple pen apple",
"pine applepen apple"
]
Explanation: Note that you are allowed to reuse a dictionary word.
Example 3:
Input:
s = "catsandog"
wordDict = ["cats", "dog", "sand", "and", "cat"]
Output:
[]
思路 1 - 时间复杂度: O(len(s)^2)- 空间复杂度: O(1)******
dfs, 超时
class Solution:
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: List[str]
:rtype: List[str]
"""
res = []
def dfs(idx, tmp_res):
if idx == len(s):
res.append(tmp_res[:-1])
for i in range(idx+1, len(s)+1):
if s[idx:i] in wordDict:
dfs(i, tmp_res+s[idx:i]+' ')
dfs(0, '')
return res
思路 2 - 时间复杂度: O(len(s)^2)- 空间复杂度: O(len(s)^2)******
把word break i 结合起来减少时间复杂度的作法。
做法如下,聪明:
就是对于每一个s,我们来check它是否可以break,如果不可以,就不用做相应的操作了
但是其实
s = "aaaaaa"
wordDict = ["a","aa","aaa"]
还是会loop很多次
不过像
s = "aabbb"
wordDict = ["a","abbb"]
就会减少很多loop次数
beats 10.10%
class Solution:
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: List[str]
:rtype: List[str]
"""
res = []
def dfs(idx, tmp_res):
if idx == len(s):
res.append(tmp_res[:-1])
if not self.check(s[idx:], wordDict):
return
for i in range(idx+1, len(s)+1):
if s[idx:i] in wordDict:
dfs(i, tmp_res+s[idx:i]+' ')
dfs(0, '')
return res
def check(self, s, wordDict):
ok = [True]
for i in range(1, len(s) + 1):
ok += any(ok[j] and s[j:i] in wordDict for j in range(i)),
return ok[-1]
思路 3 - 时间复杂度: O(len(wordDict) * len(res))- 空间复杂度: O(len(s)^2)******
可以用cache加快速度,beats 89.77%
class Solution:
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: List[str]
:rtype: List[str]
"""
return self.helper(s, wordDict, {})
def helper(self, s, wordDict, memo):
if s in memo:
return memo[s]
if not s:
return []
res = []
for word in wordDict:
if not s.startswith(word):
continue
if len(word) == len(s):
res.append(word)
else:
resultOfTheRest = self.helper(s[len(word):], wordDict, memo)
for item in resultOfTheRest:
item = word + ' ' + item
res.append(item)
memo[s] = res
return res