转自:http://segmentfault.com/blog/exploring/
LCS
问题描述
定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。 例如:输入两个字符串 BDCABA 和 ABCBDAB,字符串 BCBA 和 BDAB 都是是它们的最长公共子序列,则输出它们的长度 4,并打印任意一个子序列. (Note: 不要求连续)
判断字符串相似度的方法之一 - LCS 最长公共子序列越长,越相似。
July 10分钟讲LCS视频:http://www.julyedu.com/video/play/id/9
复杂度
对于一般性的 LCS 问题(即任意数量的序列)是属于 NP-hard。但当序列的数量确定时,问题可以使用动态规划(Dynamic Programming)在多项式时间解决。可达时间复杂度:O(m*n)
暴力方法
动态规划方法
最优子结构性质: 设序列 X=<x1, x2, …, xm>
和 Y=<y1, y2, …, yn>
的一个最长公共子序列 Z=<z1, z2, …, zk>
,则:
- 若
xm = yn
,则zk = xm = yn
则Zk-1
是Xm-1
和Yn-1
的最长公共子序列;
2. 若 xm ≠ yn
, 要么Z
是 Xm-1
和 Y
的最长公共子序列,要么 Z
是X
和 Yn-1
的最长公共子序列。 2.1 若 xm ≠ yn
且 zk≠xm
,则 Z
是 Xm-1
和 Y
的最长公共子序列; 2.2 若 xm ≠ yn 且 zk ≠yn
,则 Z
是X
和 Yn-1
的最长公共子序列。 综合一下2 就是求二者的大者
递归结构:
递归结构容易看到最长公共子序列问题具有子问题重叠性质。例如,在计算 X
和 Y
的最长公共子序列时,可能要计算出 X
和 Yn-1
及 Xm-1
和 Y
的最长公共子序列。而这两个子问题都包含一个公共子问题,即计算 Xm-1
和 Yn-1
的最长公共子序列。
递归结构容易看到最长公共子序列问题具有子问题重叠性质。例如,在计算 X
和 Y
的最长公共子序列时,可能要计算出 X
和 Yn-1
及 Xm-1
和 Y
的最长公共子序列。而这两个子问题都包含一个公共子问题,即计算Xm-1
和 Yn-1
的最长公共子序列。
计算最优值: 子问题空间中,总共只有O(m*n)
个不同的子问题,因此,用动态规划算法自底向上地计算最优值能提高算法的效率。
长度表C 和 方向变量B: