总结:
这个题目有三种方法,单最后一种是适用于大规模的字符串匹配,我暂时还不想学.
两种常规算法,动态规划和双指针
动态规划:
在具有大量重复计算时,通过每一步走最优解,且后序步骤不会影响到前面时所采用的一种方法,集中体现就是可以写出状态转移方程
而在这个字符串问题中,我可以通过求其子集的最长公共子串
然后在:
if s[i]==t[j]:
dp[i][j]=1+dp[i-1][j-1]
else:
dp[i][j]=max(dp[i-1][j],dp[i][j-1])
双指针:
上面是存在冗余操作的
其实这里我只需要判断s是不是t的子序列,只需要判断s
那么我完全可以双指针,一个指向s,一个指向t
然后可以匹配
动态规划写法,依次判断对应的连续子集的最长公共子序列
然后如果len(s)<len(t),那么不考虑任何情况s和t最长的公共子序列最多是s
也就是说如果s是t的子序列,那么一定是公共子序列的最长情况
所以最后就是判断dp[-1][-1]s和t的公共子序列长度是否达到了len(s)
def fun1(s,t):
'''
动态规划写法
假设有 s='abc' t='ahbgdc'
dp=[[0*len(s)] for j in range(len(t))]
while i<len(s) and j<len(t):
if s[i]==t[j]:
#这说明是前面的子序列
dp[i][j]=1+dp[i-1][j-1]
else:
s[i]!=t[j]的时候,这时候你肯定是不可以直接加1的,但你也不能不加
为什么,当s添加元素,与t之前的末尾元素相匹配时,长度自然也可加1
dp[i][j]=max(dp[i-1][j],dp[i][j-1])
:param s:
:param t:
:return:
'''
if len(s)>len(t):
return False
dp = [[0 for j in range(len(t)+1)] for i in range(len(s)+1)]#当有一个是0是,公共长度为0
for i in range(1,len(s)+1):
for j in range(1,len(t)+1):
if s[i-1] == t[j-1]:
# 这说明是前面的子序列
dp[i][j] = 1 + dp[i - 1][j - 1]
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
#在循环结束时,s肯定已经被判断
if dp[-1][-1]==len(s):
return True
else:
return False
双指针代码,上面的代码存在冗余操作,将所有的可能情况都判断了一遍
def fun2(s,t):
'''
上面是通用的一个模板,他其实是可以用来找出所有的公共子序列,只是附带着可以找出s是不是t的子序列
因而会存在操作上的冗余
其实就是简单的判断一下
while i<len(s) and j<len(t):
if s[i]==t[j]:
i+=1
j+=1
else:
j+=1
:param s:
:param t:
:return:
'''
i,j=0,0
while i < len(s) and j < len(t):
if s[i] == t[j]:
i += 1
j += 1
else:
j += 1
if i==len(s):
return True
else:
return False