一、题目描述
给你一个字符串 s
和一个字符串列表 wordDict
作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s
则返回 true
。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
二、思路
这个题目其实就是用字典中的字符串不断的匹配字符串s,但是暴力算法的时间复杂度是O()。但是实际很多匹配是重复计算,这就需要用到记忆化回溯了。首先从开始递归每一种解法,并保存递归的结果。
记忆化回溯的基本思想
- 递归回溯:我们在回溯算法的框架下进行递归,尝试所有可能的解。
- 缓存结果:在每次递归时,判断当前子问题是否已经计算过,如果计算过,则直接返回缓存的结果;如果没有计算过,则计算该子问题的解,并将结果存入缓存。
- 避免重复计算:通过缓存子问题的解,减少回溯中相同子问题的重复计算,提高算法效率。
三、实现代码
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
dp = [True] * (len(s)+1)
return self.match(s, wordDict,dp)
def match(self, subString: str, wordDict: List[str],dp:List[bool]) -> bool:
if not dp[len(subString)]:
return False
if subString is None or len(subString) == 0:
return True
for word in wordDict:
if subString.startswith(word) and self.match(subString[len(word):], wordDict,dp):
return True
dp[len(subString)] = False
return False