解题思路:
这道题一眼看去,就死类似于单词拆分I的深度优先搜索就可以解决的题目,不过这里升级了,就是要把每一种切分结果都要返回。
具体代码如下:
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
mem = {}
tmp = self.dfs(s, wordDict, mem)
res = []
for item in tmp:
res.append(' '.join(item))
return res
def dfs(self, s, wordDict, mem):
if self.check(s, wordDict) == False:
return []
if s in mem.keys():
return mem[s]
if s == '':
return [[]]
res = []
for i in range(1, len(s) + 1):
if s[:i] in wordDict and self.check(s[i:], wordDict):
substr = self.dfs(s[i:], wordDict, mem)
for item in substr:
res.append([s[:i]] + item)
return res
def check(self, s, wordDict):
if s in wordDict:
return True
index_set = [False]*(len(s) + 1)
index_set[0] = True
for i in range(1, len(s) + 1): # i [1, 8]
for idx in range(i): # idx [0, 7]
if index_set[i] == False and index_set[idx] and s[idx:i] in wordDict:
index_set[i] = True
return index_set[-1]
改进思路:
1.反向判断,判断每一个字符的位置到最终的位置之间的子串是否可分,判断完之后将这个bool数组保存起来;
2.正向dfs,利用反向判断的信息可以快速判断后面是否可以分解,从而避免不必要的计算量;
具体代码如下:
class Solution:
'''反向判断'''
def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
judges = self.get_judgement(s, wordDict)
if judges[0] == False:
return []
mem = {}
res = []
tmp = self.dfs(s, wordDict, mem, judges)
for item in tmp:
res.append(' '.join(item))
return res
def dfs(self, s, wordDict, mem, judges):
if s in mem.keys():
return mem[s]
if s == '':
return [[]]
res = []
for i in range(1, len(s)+1):
#先判断字典中是不是存在这个字符串,然后判断这个字符串后面是否能分解
if s[:i] in wordDict and judges[i]:
substr = self.dfs(s[i:], wordDict, mem, judges[i:])
for item in substr:
res.append([s[:i]] + item)
mem[s] = res
return res
def get_judgement(self, s, wordDict): #len(s) = 5
res = [False] * (len(s) + 1)
res = [False] * (len(s) + 1)
res[-1] = True
for i in range(len(s))[::-1]: #i 7 to 0
for ptr in range(i+1, len(s)+1)[::-1]: #ptr 8 to i+1
if res[i] == False and res[ptr] and s[i:ptr] in wordDict:
res[i] = True
return res
经过改进之后,时间复杂度得到了很大的提升,可以提交观察结果查看。