原文连接:https://www.techiedelight.com/longest-common-subsequence/spa
最长公共子序列 (longest common subsequence, LCS) 问题就是要找到给定两个字符序列种出现顺序相同的最长子序列的问题,或者说经过删除第一个原始序列中的某些项和删除第二个原始序列中的某些项而获得的相同的最长的子序列。element
这个问题不一样于找公共字符串的问题,由于子序列并不须要占据原始序列中一片连续的位置。字符串
例以下面的两个字符序列 X 和 Yget
X: ABCBDABio
Y: DBCABAclass
LCS 的长度是 4programming
LCS 能够是:BDAB,BCAB 和 BCBA方法
最简单的作法就是检查 \(X[1...m]\) 的每一个子序列,看它是否一样也是 \(Y[1...n]\) 的子序列。因为 X 的全部可能的子序列有 \(2^{m}\) 个,因此这种解决方法的复杂度是 \(O(n*2^{m})\)。im
LCS 问题有 optimal substructure,这意味着该问题能够被分解成更小的,简单的"子问题",而这些问题又能够继续分解成更加简单的子问题,直到最后问题变得平凡。qq
以长度为 m 的序列 \(X\) 和 长度为 n 的子序列 \(Y\)为例,这里假定它们以相同的元素结尾。
为了找到它们的 LCS,能够经过移除最后一个元素来减小每一个序列的长度,而后找到缩短后的序列的 LCS,而后将找到的 LCS 追加移除的元素。因此咱们能够获得结论:
\[LCS(X[1..m], Y[1..n]) = LCS(X[1..m-1], Y[1..n-1]) + X[m] \qquad if \; X[m] = Y[n]\]
如今假设这两个序列结尾的字符并不相同。
那么 \(X\) 和 \(Y\) 的 LCS 则是 \(LCS(X[1..m-1], Y[1..n])\) 和 \(LCS(X[1..m], Y[1..n-1])\) 中较长的那个。为了理解这个性质,咱们能够如下面两个序列为例:
X: ABCBDAB (n elements)
Y: BDCABA (m elements)
这两个序列的 LCS 要么以 B 结尾(序列 \(X\) 的最后一个字符),要么不是。
Case 1: