先理解题意,字典中的每个单词可以重复使用,也可以不使用,直到能够拼出s
思路
动态规划
第一种写法
建立dp表,dp[0]置为True,那么dp[i]就表示s的前i-1个字符时是否完全能够通过字典中的元素拆分表示,是为True,不是为False
动态方程为: dp[i]=True and s[i:j+1] in wordDict,dp[j]才为True
即对于每一个i,检查从s的j = i+1位置到s的结尾是否可以用字典中的字符串表示
代码:
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
n = len(s)
dp = [True] + [False] * n
for i in range(n):
if dp[i]: #dp[i]为True,才有求下去的意义
for j in range(i + 1, n + 1):
if s[i:j] in wordDict:
dp[j] = True
return dp[-1]
第二种写法
dp[i]表示s前i个字符能否被字典拆分表示,从位置0上一直到位置i上进行判断,而优化的方法是不需要每次都从s[0]位置开始搜索,而只需要考虑字典中的最大长度字符串maxlen
,从i-maxlen
处到i
进行搜索
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
n = len(s)
dp = [True] + [False] * n
maxlen = 0
for word in wordDict:
maxlen = max(maxlen, len(word))
for i in range(1,n+1):
maxlen = max(0,maxlen)
for j in range(i - maxlen,i): #不需要从0位置开始搜索
if dp[j] and s[j:i] in wordDict:
dp[i] = True
return dp[-1]