[Algorithms] Longest Common Subsequence
The Longest Common Subsequence (LCS) problem is as follows:
Given two sequences s and t, find the length of the longest sequence r, which is a subsequence of both s and t.
Do you know the difference between substring and subequence? Well, substring is a contiguous series of characters while subsequence is not necessarily. For example, "abc" is a both a substring and a subseqeunce of "abcde" while "ade" is only a subsequence.
This problem is a classic application of Dynamic Programming. Let's define the sub-problem (state) P[i][j] to be the length of the longest subsequence ends at i of s and j of t. Then the state equations are
- P[i][j] = max(P[i][j - 1], P[i - 1][j]) if s[i] != t[j];
- P[i][j] = P[i - 1][j - 1] + 1 if s[i] == t[j].
This algorithm gives the length of the longest common subsequence. The code is as follows.
int longestCommonSubsequence(string s, string t) {
int m = s.length(), n = t.length();
vector<vector<int> > dp(m + , vector<int> (n + , ));
for (int i = ; i <= m; i++)
for (int j = ; j <= n; j++)
dp[i][j] = (s[i - ] == t[j - ] ? dp[i - ][j - ] + : max(dp[i - ][j], dp[i][j - ]));
return dp[m][n];
}
Well, this code has both time and space complexity of O(m*n). Note that when we update dp[i][j], we only need dp[i - 1][j - 1], dp[i - 1][j] and dp[i][j - 1]. So we simply need to maintain two columns for them. The code is as follows.
int longestCommonSubsequenceSpaceEfficient(string s, string t) {
int m = s.length(), n = t.length();
int maxlen = ;
vector<int> pre(m, );
vector<int> cur(m, );
pre[] = (s[] == t[]);
maxlen = max(maxlen, pre[]);
for (int i = ; i < m; i++) {
if (s[i] == t[] || pre[i - ] == ) pre[i] = ;
maxlen = max(maxlen, pre[i]);
}
for (int j = ; j < n; j++) {
if (s[] == t[j] || pre[] == ) cur[] = ;
maxlen = max(maxlen, cur[]);
for (int i = ; i < m; i++) {
if (s[i] == t[j]) cur[i] = pre[i - ] + ;
else cur[i] = max(cur[i - ], pre[i]);
maxlen = max(maxlen, cur[i]);
}
swap(pre, cur);
fill(cur.begin(), cur.end(), );
}
return maxlen;
}
Well, keeping two columns is just for retriving pre[i - 1], we can maintain a single variable for it and keep only one column. The code becomes more efficient and also shorter. However, you may need to run some examples to see how it achieves the things done by the two-column version.
int longestCommonSubsequenceSpaceMoreEfficient(string s, string t) {
int m = s.length(), n = t.length();
vector<int> cur(m + , );
for (int j = ; j <= n; j++) {
int pre = ;
for (int i = ; i <= m; i++) {
int temp = cur[i];
cur[i] = (s[i - ] == t[j - ] ? pre + : max(cur[i], cur[i - ]));
pre = temp;
}
}
return cur[m];
}
Now you may try this problem on UVa Online Judge and get Accepted:)
Of course, the above code only returns the length of the longest common subsequence. If you want to print the lcs itself, you need to visit the 2-d table from bottom-right to top-left. The detailed algorithm is clearly explained here. The code is as follows.
int longestCommonSubsequence(string s, string t) {
int m = s.length(), n = t.length();
vector<vector<int> > dp(m + , vector<int> (n + , ));
for (int i = ; i <= m; i++)
for (int j = ; j <= n; j++)
dp[i][j] = (s[i - ] == t[j - ] ? dp[i - ][j - ] + : max(dp[i - ][j], dp[i][j - ]));
int len = dp[m][n];
// Print out the longest common subsequence
string lcs(len, ' ');
for (int i = m, j = n, index = len - ; i > && j > ;) {
if (s[i - ] == t[j - ]) {
lcs[index--] = s[i - ];
i--;
j--;
}
else if (dp[i - ][j] > dp[i][j - ]) i--;
else j--;
}
printf("%s\n", lcs.c_str());
return len;
}
[Algorithms] Longest Common Subsequence的更多相关文章
- [Algorithms] Using Dynamic Programming to Solve longest common subsequence problem
Let's say we have two strings: str1 = 'ACDEB' str2 = 'AEBC' We need to find the longest common subse ...
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- LintCode Longest Common Subsequence
原题链接在这里:http://www.lintcode.com/en/problem/longest-common-subsequence/ 题目: Given two strings, find t ...
- [UCSD白板题] Longest Common Subsequence of Three Sequences
Problem Introduction In this problem, your goal is to compute the length of a longest common subsequ ...
- LCS(Longest Common Subsequence 最长公共子序列)
最长公共子序列 英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已 ...
- Longest Common Subsequence
Given two strings, find the longest common subsequence (LCS). Your code should return the length of ...
- Longest Common Subsequence & Substring & prefix
Given two strings, find the longest common subsequence (LCS). Your code should return the length of ...
- Dynamic Programming | Set 4 (Longest Common Subsequence)
首先来看什么是最长公共子序列:给定两个序列,找到两个序列中均存在的最长公共子序列的长度.子序列需要以相关的顺序呈现,但不必连续.例如,"abc", "abg", ...
- Lintcode:Longest Common Subsequence 解题报告
Longest Common Subsequence 原题链接:http://lintcode.com/zh-cn/problem/longest-common-subsequence/ Given ...
随机推荐
- 升级macOS Sierra系统 导致错误 app: resource fork, Finder information, or similar detritus not allowed
前几天刚升级了macOS Sierra系统,顿时感觉入坑了,本来好好的项目报如下错误: app: resource fork, Finder information, or similar detri ...
- java基础讲解14-----IO
package com.io; import java.io.File;import java.io.IOException; public class IoClass { /** ...
- jQuery Growl 插件(消息提醒)
jQuery Growl 插件(消息提醒) 允许您很容易地在一个覆盖层显示反馈消息.消息会在一段时间后自动消失,不需要单击"确定"按钮等.用户也可以通过移动鼠标或点击关闭按钮加快隐 ...
- angularJS使用内置服务
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...
- jmeter ---集合点使用方法:Synchronizing Timer
LR中集合点可以设置多个虚拟用户等待到一个点,同时触发一个事务,以达到模拟真实环境下多个用户同时操作,实现性能测试的最终目的. jmeter中使用Synchronizing Timer实现Lr中集合点 ...
- THINKPHP3.2视频教程
http://edu.51cto.com/lesson/id-24504.html lunix视频教程 http://bbs.lampbrother.net/read-htm-tid-161465.h ...
- 使用SQLite
SQLite是一种嵌入式数据库,它的数据库就是一个文件.由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以集成. Python就 ...
- MySQL触发器更新本表数据异常:Can't update table 'tbl' in stored function/trigger because it
MySQL触发器更新本表数据异常:Can't update table 'tbl' in stored function/trigger because it 博客分类: 数据库 MySQLJava ...
- hdu Distant Galaxy(遥远的银河)
Distant Galaxy Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- ajax请求的data数据格式
ajax提交data类型 一.问题来源 今天使用ajax时,发现get传data时,传递json字符串时传不过去参数,所以做了一些实验测试ajax的get和post的传递data时的不同. 二.概念 ...