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

  1. P[i][j] = max(P[i][j - 1], P[i - 1][j]) if s[i] != t[j];
  2. 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的更多相关文章

  1. [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 ...

  2. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  3. LintCode Longest Common Subsequence

    原题链接在这里:http://www.lintcode.com/en/problem/longest-common-subsequence/ 题目: Given two strings, find t ...

  4. [UCSD白板题] Longest Common Subsequence of Three Sequences

    Problem Introduction In this problem, your goal is to compute the length of a longest common subsequ ...

  5. LCS(Longest Common Subsequence 最长公共子序列)

    最长公共子序列 英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已 ...

  6. Longest Common Subsequence

    Given two strings, find the longest common subsequence (LCS). Your code should return the length of  ...

  7. Longest Common Subsequence & Substring & prefix

    Given two strings, find the longest common subsequence (LCS). Your code should return the length of  ...

  8. Dynamic Programming | Set 4 (Longest Common Subsequence)

    首先来看什么是最长公共子序列:给定两个序列,找到两个序列中均存在的最长公共子序列的长度.子序列需要以相关的顺序呈现,但不必连续.例如,"abc", "abg", ...

  9. Lintcode:Longest Common Subsequence 解题报告

    Longest Common Subsequence 原题链接:http://lintcode.com/zh-cn/problem/longest-common-subsequence/ Given ...

随机推荐

  1. JSR 303 - Bean Validation 介绍及最佳实践(转)

    JSR 303 – Bean Validation 是一个数据验证的规范,2009 年 11 月确定最终方案.2009 年 12 月 Java EE 6 发布,Bean Validation 作为一个 ...

  2. 【VBA研究】利用DateAdd函数取上月或上年同期的日期

    作者:iamlaosong DateAdd函数返回一个日期.这一日期加上了一个时间间隔.通过这个函数能够计算非常多我们须要的日期,比方上月上年同期日期等. 语法 DateAdd(interval, n ...

  3. c语言中有bool型变量吗?

    C语言里面是没有bool(布尔)类型的,C++里面才有,这就是说,在C++里面使用bool类型是没有问题的. bool类型有只有两个值:true =1 .false=0. 但是,C99标准里面,又定义 ...

  4. memcache概念浅谈及名称混乱之区分

    关于memcache这个现在应用广泛的组件,大大提高的网站的响应速度,也方便了程序开发缓存的应用.但是目前针对memcache,网上的资料 大同小异,尤其基于LAMP的网站居多,php/pcel又有两 ...

  5. 点滴积累【C#】---C#实现上传照片到物理路径,并且将地址保存到数据库,

    效果: 思路: 首先,获取图片物理地址,然后进行判断将图片保存到文件夹下,再将图片的信息保存到数据库. 数据库: create table image1 ( ID ,) primary key, Im ...

  6. [elk]logstash grok原理

    logstash语法 http://www.ttlsa.com/elk/elk-logstash-configuration-syntax/ https://www.elastic.co/guide/ ...

  7. Android Studio怎样import module(针对非gradle)

    相同的,非gradle编译的project和gradle编译的在import module上相同有一些差别. 包含操作上,显示上的一些差别,曾经的文章中,仅仅要没有标注"非gradle&qu ...

  8. eclipse调试的时候查看变量出现com.sun.jdi.InvocationException occurred invoking method.

    症状:如题 分析/解决方案:你的toString抛出了异常,去查看toString的代码是不是有问题,比如说空指针什么的

  9. gcc 编译动态库和静态库

    Linux C 编程入门之一:gcc 编译动态库和静态库 cheungmine 2012 参考: C程序编译过程浅析 http://blog.csdn.net/koudaidai/article/de ...

  10. eclipse JavaEE版"javax.servlet.http.HttpServlet" was not found on the Java Build Path问题的解决办法

    使用eclipse JavaEE 版,新建 Dynamic Web Project 项目.在项目里添加 JSP 文件,会在文件头部出现错误提示.提示语句为:The superclass "j ...