单词拆分(139)
题目
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:
拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 1:
输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以被拆分成 “leet code”。
示例 2:
输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
输出: true
解释: 返回 true 因为 “applepenapple” 可以被拆分成 “apple pen apple”。
注意你可以重复使用字典中的单词。
示例 3:
输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false
思路
本题属于动态规划,设立一个数组dp判断,dp[i]表示前i个字符组成的字符串能否成功拆分。从i= 0开始之后每次添加了一个字符,循环判断能否与之前的组合成新的划分。时间复杂度为n*n
代码
class Solution:
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: List[str]
:rtype: bool
"""
dp = [True]
lenght = len(s)
i = 1
while i < lenght + 1:
dp.append(False)
j = i-1
while j >= 0:
if dp[j] and s[j:i] in wordDict:
dp[i] = True
break
j -= 1
i += 1
return dp[len(s)]
单词拆分2(140)
题目
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
说明:
分隔时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 1:
输入:
s = “catsanddog”
wordDict = [“cat”, “cats”, “and”, “sand”, “dog”]
输出:
[
“cats and dog”,
“cat sand dog”
]
示例 2:
输入:
s = “pineapplepenapple”
wordDict = [“apple”, “pen”, “applepen”, “pine”, “pineapple”]
输出:
[
“pine apple pen apple”,
“pineapple pen apple”,
“pine applepen apple”
]
解释: 注意你可以重复使用字典中的单词。
思路
一开始的思路是根据上一题的方法,任然采用动态规划的方法,只不过在每一次动态规划过程中不仅记录是否可以拆分,还要把所有的拆分形式记录下来,但在最后提交时,卡在了第31个测试集上,原因是内存消耗过多。无奈只能用其他的方法。再阅读了有关资料后,使用dp(动态规划)判断能否分割,如果可以分割采用DFS分割。DFS分割的思路即每次从字典中找可以与字符串开头匹配的,并将后续的传入做下一次迭代。
简单分析了一下性能后,的确后者方法无论在空间或者时间上都有巨大优势,动态规划适用于拆分的特例(如能否拆分的判断),对于遍历的问题还需要用搜索到方法。
代码
class Solution:
"""
采用139的动态规划的思路,内存消耗过大,失败
"""
def wordBreak(self, s: str, wordDict) :
m = len(s)
yes = [False]*(m+1)
yes[0] = True
ans = {}
for i in range(m+1):
ans[i]=[]
for i in range(1,m+1):
if i-smax-3>0:
for j in range(i-1,-1,-1) :
if yes[j] is True and s[j:i] in wordDict:
yes[i]=True
if len(ans[j])==0 :
ans[i].append(s[j:i])
else:
for k in ans[j]:
temp = k+' '+s[j:i]
ans[i].append(temp)
return ans[m]
class Solution(object):
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: List[str]
:rtype: List[str]
"""
tmp=wordDict[:]
wordDict={}
for w in tmp:
wordDict[w]=1
res=[]
tmp=[]
def check(s): # 判断是不是可以拆分
l=len(s)
dp=[False]*(l+1)
dp[0]=True
for i in range(l):
for j in range(i,-1,-1):
if dp[j] and s[j:i+1] in wordDict:
dp[i+1]=True
break
return dp[l]
def dfs(s):
if not s:#s为空拆分到头
res.append(tmp[:])
return
for word in wordDict:
l=len(word)
if word==s[:l]:
tmp.append(word)
dfs(s[l:])
tmp.pop()
if check(s):
dfs(s)
r=[]
for e in res:
r.append(" ".join(e))#转化形式
return r