题目:
给你一个字符串 s 和一个字符串列表 wordDict 作为字典,判定 s 是否可以由空格拆分为一个或多个在字典中出现的单词。
说明:拆分时可以重复使用字典中的单词。
解答:
方法一:回溯,超时
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
#回溯
def tracebacking(s,wordset,startidx):
if startidx==len(s):
return True
for i in range(startidx,len(s)):
subs=s[startidx:i+1]
if (subs in wordset) and tracebacking(s,wordset,i+1):
return True
return False
return tracebacking(s,wordDict,0)
改进:记忆化搜索,依旧超时
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
#回溯,记忆化搜索
def tracebacking(s,wordset,memory,startidx):
if startidx==len(s):
return True
if memory[startidx]:
return True
for i in range(startidx,len(s)):
subs=s[startidx:i+1]
if (subs in wordset) and tracebacking(s,wordset,memory,i+1):
memory[startidx]=True #以startidx开始的子串可以被拆分
return True
return False
memory=[False]*len(s)
return tracebacking(s,wordDict,memory,0)
方法二:动态规划
时间复杂度:O(n^3)
空间复杂度:O(n)
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
#dp[i]:字符串长度为i的话,dp[i]为true,表示可以拆分为一个或多个在字典中出现的单词
n=len(s)
dp=[False]*(n+1)
dp[0]=True
#外层背包,内层物品
#背包容量:1-n
for i in range(1,n+1):
for j in range(i):
subs=s[j:i]
#若s[0:j]可被拆分,且s[j:i]可被拆分,则s[0:i]可被拆分
if dp[j] and (subs in wordDict):
dp[i]=True
return dp[n]