Given a non-empty string s and a dictionary wordDict containing a list of non-emptywords, 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" ]
最简单的是使用backtrack,代码类似dfs,但是会超时。因为子问题会被重复计算。
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
ans = []
wordset = set(wordDict)
def match(curr, start):
word = ''
for i in range(start, len(s)):
c = s[i]
word += c
if word in wordset:
if i == len(s) - 1:
ans.append(' '.join(curr + [word]))
return
else:
match(curr + [word], i + 1)
match([], 0)
return ans
为了使用memory数组来记录答案,改写上面的做法,令match函数只传入一个start的index,直接将从start开始到最后的子字符串作为子问题求解,并将结果ans作为返回值(原来是直接把结果加上当前的前缀就加入父级的变量了)。注意,直接把当前的结果加入ans就好了,而不用加上前缀,前缀已经不属于子问题了。
用一个for循环来遍历子问题的返回值,与当前的前缀进行组合,加入父问题的ans。
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
wordset = set(wordDict)
mem = {}
def match(start):
if start in mem.keys():
return mem[start]
ans = []
word = ''
for i in range(start, len(s)):
c = s[i]
word += c
if word in wordset:
if i == len(s) - 1:
ans.append(word)
mem[start] = ans
return ans
else:
for tail in match(i + 1):
if tail != '':
ans.append(word + ' ' + tail)
elif i == len(s) - 1:
mem[start] = ans
return ans
return match(0)