所有不同的序列串-----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 ...
随机推荐
- python 环境安装和卸载1
同事换了新机器,系统从win7变为了win10,因此需要重新安装python环境啦!不废话,直奔主题. A 安装 一.进入python官网 www.python.org 进入downloads-&g ...
- deep learning入门:感知机
权重和偏置 import numpy as np # 求x1 and x2 def AND(x1, x2): x = np.array([x1, x2]) w = np.array([0.5, 0.5 ...
- redux&&createStore
const createStore = (reducer,presetState, enhancer) => { if (typeof presetState === "functio ...
- 安装与配置apache WEB服务器(Linux环境)
Linux环境下安装一个软件的方式多数为两种: 1.通过命令从远程源下载自动默认安装 2.编译安装 第一种较为简单,直接通过 yum 或者 apt-get 直接安装即可,但是对我来说,编译安装可能更加 ...
- make capslock+hjkl as arrows
Solution 2 (probably better) I was happy with solution 1, until I realized I couldn't use the key bi ...
- java三种注释以及参数涵义(转)
原文地址:https://www.cnblogs.com/miys/p/4bf714ce33068dcf9ac6526309c9b5e6.html 单行注释:// 注释内容 多行注释:/*... 注释 ...
- Ubuntu 下生成 python 环境安装文件 requirements.txt
参考: 查找python项目依赖并生成requirements.txt Ubuntu 下生成 python 环境安装文件 requirements.txt 首先通过 pip 安装pyreqs模块: p ...
- linux 系统下安装多个php版本
思路: 下载不同的php源码包,解压后安装在不同的目录下,修改php-fpm监听的端口号 php安装配置参数: ./configure --prefix=/usr/local/php71 --exec ...
- js可拖拽的div
function chatDrag(div1) { div1.onmousedown = function (ev) { var oevent = ev || event; var distanceX ...
- 牛客 黑龙江大学程序设计竞赛重现 19-4-25 D
题意: n项工作 1~n 工时s[i] ~e[i], 工时有覆盖的工作不能被同一台机器同时操作, 问完成所有工作的最少机器数 思路:前缀差分和 e.g. a 2 3 4 ...