所有不同的序列串-----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 ...
随机推荐
- MySql 8.0 C#连接报错 MySql.Data.MySqlClient.MySqlException (0x80004005): Authentication to host '12.118.224.181' for user 'root' using method 'caching_sha2_password' failed with message: Reading from t
解决方法 在连接字符串后面加上 SslMode=None
- javascript prop和attr的区别
在网上找了一些资料,通过自己去寻找,尝试,此次做一次总结. 1/ attr()是jQuery 1.0版本就有的函数, prop()是jQuery 1.6版本新增的函数.毫无疑问,在1.6之前, ...
- linux下配置zookeeper注册中心及运行dubbo服务
dubbo和zookeeper的关系 简单来说打个比方:dubbo就是动物园的动物,zookeeper是动物园.如果游客想看动物的话那么就去动物园看.比如你要看老虎,那么动物园有你才能看到.换句话说我 ...
- dao层、service和action的运用和区别
DAO层叫数据访问层,全称为data access object,属于一种比较底层,比较基础的操作,对于数据库的操作,具体到对于某个表的增删改查, 也就是说某个DAO一定是和数据库的某一张表一一对应的 ...
- abap 增强查找小程序
*&---------------------------------------------------------------------* *& Report ZEXIT *& ...
- 剑指offer 15:反转链表
题目描述 输入一个链表,反转链表后,输出新链表的表头. 法一:迭代法 /* public class ListNode { int val; ListNode next = null; ListNod ...
- VS的工作目录和输出目录
C+ +项目,解决方案总文件夹下就只包含解决方案配置文件sln和一个项目总文件夹和一个Debug文件夹以及一个Release文件夹(共四个东东,其中Debug和Release文件夹中存放最终生成的结果 ...
- mybatis ResultMap详解
前言 MyBatis是基于“数据库结构不可控”的思想建立的,也就是我们希望数据库遵循第三范式或BCNF,但实际事与愿违,那么结果集映射就是MyBatis为我们提供这种理想与现实间转换的手段了,而res ...
- Android屏幕适配框架-(今日头条终极适配方案)
在Android开发中,屏幕适配是一个非常头痛的问题,因而为了去进行屏幕适配,作为程序员,是呕心沥血,历经磨难,哈哈 我们之前做屏幕适配一般都会用到一下两种方式: 第一种就是宽高限定符适配,什么是宽高 ...
- vue2 inheritAttrs、attrs和attrs和listeners使用
inheritAttrs.attrs和attrs和listeners使用场景: 组件传值,尤其是祖孙组件有跨度的传值. (1)inheritAttrs 属性说明:https://cn.vuejs.or ...