总结:
暴力法就不说了,提交没有通过,并且思想很简单
动态规划:
在具有大量重复计算是,通过每一步走最优解,且后序不会影响到前面的
最优解,直观体现就是状态转移方程
字符串动态规划问题
我现在遇到的都是,求子集的最优解
那么这个题呢?
如cars car c a rs
①c 判断是否在dic中
②ca 判断 空字符和 ca是否在 不在 继续判断 c和a 在 dp[2]=True
③car 判断空字符和car是否在 在dp[3]=True
④cars 判断空字符和cars是否在 buzai 判断c ars是否在 不在
判断ca rs 是否在 在返回True
这里没有ca 只有c a所以肯定不能直接判断cars 比如c ars ca rs car s
所以我是需要使用前面的状态的
如果是cars c a r s呢
①c 判断是否在dic中在 True
②ca 判断 True
③car 判断True
④cars 判断 True
所以可以看到状态转移方程为
dp[i]=dp[j] and s[j:i-1:]
为什么前面要写 dp[j] 后面可以写s[j:i-1:]呢?
dp是保存了0~i-1的状态了的
所以对于 cars 假如说没有rs 只有r 和 s
那么我在 ca rs 的时候返回的是False
car s 的是否返回的是True
所以只要是一个连续的部分就好了
我采用了暴力的方式来求解
但是忽略了一个问题
当单词s为 cars 单词表为car ca rs
我首先判断car 将单词s变为了 s
所以没有做到所有可能情况的全排列
'''
理解题目:
--s必须是连续的部分进行拆分
--worddict中的单词可以重复使用
所以就变成了什么?
我可以直接拿worddict中的每一个 单词
每一次都对s进行一遍比对,,然后将s中比对成功的部分进行删除
直到有一次 没有对s进行删除 或者 s为空字符串了
对吧? 是的就是这样
'''
def fun1(s,wordDict):#暴力写法,提交不通过
pre=s #记录s的上一次状态,使得当循环没有使得s的状态改变时改变
while s!='': #外层循环
for word in wordDict:
len_word=len(word)
for i in range(len(s)-len_word+1):
if word==s[i:len_word:]: #判断是否相等
s=s[:i:]+s[len_word::]
break
if pre==s:
return False
pre=s
return True
print(fun1("leetcode",["leet", "code"]))
对于字符串类型的问题,其对应的最优解
一般都是先求子集的最优解
def fun2(s,wordDict):#提交不通过
'''
"cars"
["car","ca","rs"]
可以看到,正确来讲,他是可以ca rs进行切分的
但是我在上面写的是 循环 导致了我没有全排列所有可能的拆分
就是说 我可能是 car ca rs这个顺序
也可能是 ca car rs 这个顺序
也可能是 ca ca ca 这个顺序
就是要将所有可能的拆分 全部弄一遍
:param s:
:param wordDict:
:return:
'''
dic={}
for i in range(len(wordDict)):
dic[wordDict[i]]=0
dp=[False for i in range(len(s)+1)]
dp[0]=True #默认空字符串为True
for i in range(1,len(s)+1):
for j in range(i):
if dp[j] and (s[j:i] in dic):
dp[i]=True
break
return dp[-1]
print(fun2("cars",["car","ca","rs"]))