C++版 - Lintcode 77-Longest Common Subsequence最长公共子序列(LCS) - 题解
版权声明:本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址
http://blog.csdn.net/lzuacm。
C++版 - Lintcode 77-Longest Common Subsequence最长公共子序列(LCS) - 题解
在线提交(不支持C#):
https://www.lintcode.com/problem/longest-common-subsequence/
题目描述
一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。例如,”ACE” 是 “ABCDE” 的一个子序列,而 “AEC” 不是)。
给出两个字符串,找到最长公共子序列(LCS),返回LCS的长度。
说明
- 该问题是一个经典的计算机科学问题,也是数据比较程序,比如Diff工具。它也被广泛地应用在版本控制,比如Git用它来协调文件之间的改变。它还是生物信息学应用的基础。
- https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
样例
给出“ABCD” 和 “EDCA”,这个LCS是 “A” (或 D或C),返回1
给出 “ABCD” 和 “EACB”,这个LCS是“AC”返回 2
注意:
序列可以不连续。
| ● Difficulty: | Medium |
Total Accepted: 18202
Total Submitted: 45985
Accepted Rate: 39%
Tags:
Longest Common Subsequence
LintCode Copyright
Dynamic Programming(DP)
分析:
将算式的计算结果记录在内存中,需要时直接调用该结果,从而避免无用的重复计算,提高处理效率,这在程序和算法设计中是一种行之有效的手法。动态规划就是这类手法之一。
事实上动态规划是一种记忆化递归(memorized recursive),缓存部分重要数据。另外,动态规划法可以建立递归式,通过循环顺次求出最优解。
为方便说明,这里我们用Xi" role="presentation">XiXi代表{x1,x2,⋯,xi" role="presentation">x1,x2,⋯,xix1,x2,⋯,xi},用Yj" role="presentation">YjYj代表{y1,y2,⋯,yj" role="presentation">y1,y2,⋯,yjy1,y2,⋯,yj }。那么,求长度分别为m、n的两个序列X、Y的LCS,就相当于求Xm" role="presentation">XmXm与Yn" role="presentation">YnYn的LCS。我们将其分割为局部问题进行分析。
首先,求Xm" role="presentation">XmXm与Yn" role="presentation">YnYn的LCS时要考虑以下两种情况:
当xm=yn" role="presentation">xm=ynxm=yn时,在Xm−1" role="presentation">Xm−1Xm−1与Yn−1" role="presentation">Yn−1Yn−1的LCS后面加上xm(=yn)" role="presentation">xm(=yn)xm(=yn)就是xm" role="presentation">xmxm与yn" role="presentation">ynyn的LCS。
举个例子,X=(a,b,c,c,d,a),Y={a, b, c, b, a}时xm=yn" role="presentation">xm=ynxm=yn,所以在Xm−1" role="presentation">Xm−1Xm−1与Yn−1" role="presentation">Yn−1Yn−1的LCS({a, b,c})后面加上xm" role="presentation">xmxm {=a) 即为Xm" role="presentation">XmXm与Yn" role="presentation">YnYn的LCS。
当xm≠yn" role="presentation">xm≠ynxm≠yn时,Xm−1" role="presentation">Xm−1Xm−1与Yn" role="presentation">YnYn的LCS和Xm" role="presentation">XmXm与Yn−1" role="presentation">Yn−1Yn−1的LCS中更长的一方就是Xm" role="presentation">XmXm与Yn" role="presentation">YnYn的LCS。
举个例子,X={a,b,c,c,d}, Y={a,b,c,b,a}时,Xm−1" role="presentation">Xm−1Xm−1与Yn" role="presentation">YnYn的LCS为{a,b,c),Xm" role="presentation">XmXm与Yn" role="presentation">YnYn的LCS为{a,b,c,b},因此Xm" role="presentation">XmXm与Yn−1" role="presentation">Yn−1Yn−1的LCS就是Xm" role="presentation">XmXm与Yn" role="presentation">YnYn的LCS。
这个算法对Xi" role="presentation">XiXi与Yj" role="presentation">YjYj同样适用。于是可准备下述函数,用来求解LCS的局部问题。
c[m+1][n+1]: 该二维数组中,c[i][j] 代表Xi" role="presentation">XiXi与Yj" role="presentation">YjYj的LCS的长度
c[i][j] 的值可由下述递推公式(Recursive Formula)求得。
基于上述变量和公式,可以用动态规划法求序列X与Y的LCS。
已AC代码如下:
class Solution {
public:
int longestCommonSubsequence(string &A, string &B) {
int m = A.size();
int n = B.size();
int **c = (int **)malloc((m+1) * sizeof(int *));
for (int i = 0; i < m + 1; i++)
c[i] = (int *)malloc((n+1) * sizeof(int));
int max1 = 0;
A = ' ' + A;
B = ' ' + B;
for (size_t i = 1; i <= m; i++)
c[i][0] = 0;
for (size_t j = 1; j <= n; j++)
c[0][j] = 0;
for (size_t i = 1; i <= m; i++)
{
for (size_t j = 0; j <= n; j++)
{
if (A[i] == B[j])
{
c[i][j] = c[i - 1][j - 1] + 1;
}
else
c[i][j] = max(c[i][j - 1], c[i - 1][j]);
max1 = max(max1, c[i][j]);
}
}
return max1;
}
};
Rank:
您的提交打败了 92.60% 的提交.
扩展阅读:
最长公共子序列问题 - Fogsail Chen - SegmentFault 思否
https://segmentfault.com/a/1190000008521545
C++版 - Lintcode 77-Longest Common Subsequence最长公共子序列(LCS) - 题解的更多相关文章
- lintcode 77.Longest Common Subsequence(最长公共子序列)、79. Longest Common Substring(最长公共子串)
Longest Common Subsequence最长公共子序列: 每个dp位置表示的是第i.j个字母的最长公共子序列 class Solution { public: int findLength ...
- POJ 1458 Common Subsequence(最长公共子序列LCS)
POJ1458 Common Subsequence(最长公共子序列LCS) http://poj.org/problem?id=1458 题意: 给你两个字符串, 要你求出两个字符串的最长公共子序列 ...
- LCS(Longest Common Subsequence 最长公共子序列)
最长公共子序列 英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已 ...
- LCS修改版(Longest Common Subsequence 最长公共子序列)
题目描述 作为一名情报局特工,Nova君(2号)有着特殊的传达情报的技巧.为了避免被窃取情报,每次传达时,他都会发出两句旁人看来意义不明话,实际上暗号已经暗含其中.解密的方法很简单,分别从两句话里删掉 ...
- LCS(Longest Common Subsequence)最长公共子序列
最长公共子序列(LCS)是一个在一个序列集合中(通常为两个序列)用来查找所有序列中最长子序列的问题.这与查找最长公共子串的问题不同的地方是:子序列不需要在原序列中占用连续的位置 .最长公共子序列问题是 ...
- POJ 1458 Common Subsequence 最长公共子序列 LCS
LCS #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> ...
- HDU 1159 Common Subsequence 最长公共子序列
HDU 1159 Common Subsequence 最长公共子序列 题意 给你两个字符串,求出这两个字符串的最长公共子序列,这里的子序列不一定是连续的,只要满足前后关系就可以. 解题思路 这个当然 ...
- hdu 1159 Common Subsequence(最长公共子序列 DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 Common Subsequence Time Limit: 2000/1000 MS (Jav ...
- Common Subsequence(最长公共子序列)
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. ...
随机推荐
- PDF文件优缺点
PDF的优点: 一般公司的公文档都是用PDF格式传递给员工,因为PDF可防止他人无意中触到键盘修改文件内容. 再有就是,当我们将毕业设计报告用word编辑后,发送给导师查看时,也建议采用PDF格式.因 ...
- 工作流——activiti
1.导入依赖 <!-- activiti工作流 --> <dependency> <groupId>org.activiti</groupId> < ...
- 使用Python开发的POC多线程批量执行小框架
因为代码量非常少,所以就叫“小框架”吧. 接口非常简陋,但是好处是适配POC脚本的时候很灵活,兼容性高,不需要任何研究成本. 简单来说,你按照自己的想法和习惯开发一个POC验证程序,它只要做到三点,即 ...
- unity runtime时导入fbx文件
TriLib is a Unity model loader package designed to allow the user to load various 3D model formats i ...
- DCDC设计指南二
DCDC电源设计指导:二 这一讲以一款SOP-8封装的Synchronous Step-Down Converter(同步降压转换器)电源IC为例,讲下电源的PCB设计. 如第一讲中所说,开始设计时就 ...
- 一道令人抓狂的零一背包变式 -- UVA 12563 Jin Ge Jin Qu hao
题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...
- BZOJ.4144.[AMPPZ2014]Petrol(Kruskal重构树)
BZOJ 看别人代码的时候发现哪一步都很眼熟,突然想起来,就在四个月前我好像看过还给别人讲过?mmp=v= 果然不写写就是容易忘.写了好歹忘了的时候还能复习呢(虽然和看别人的好像也没多少差别?). 首 ...
- 通过游戏来学习CSS的Flex布局
在复习Flex 布局的时候发现的了几个有趣的小游戏,在这里分享并记录几个有难度的答案 1. Flexbox Froggy 通过调整CSS样式来使各种青蛙回到对应的荷叶上,游戏默认难度为Beginner ...
- php一些高级函数方法
PHP高级函数 1.call_user_func (http://php.net/manual/zh/function.call-user-func.php) 2.get_class (http:// ...
- Flume+Kafka+Storm整合
Flume+Kafka+Storm整合 1. 需求: 有一个客户端Client可以产生日志信息,我们需要通过Flume获取日志信息,再把该日志信息放入到Kafka的一个Topic:flume-to-k ...