最长公共子序列
维基百科,自由的百科全书
最长公共子序列問題是尋找两个或多个已知数列最長的子序列。
目录 |
定義 [编辑]
一个数列
,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则
称为已知序列的最长公共子序列。
複雜度 [编辑]
對於一般性的LCS問題(即任意數量的序列)是屬於NP-hard。但當序列的數量確定時,問題可以使用动态规划(Dynamic Programming)在多項式時間解決。
解法 [编辑]
动态规划的一个计算最长公共子序列的方法如下,以两个序列
、
为例子:
设有二维数组
表示
的
位和
的
位之前的最长公共子序列的长度,则有:
其中,
当
的第
位与
的第
位完全相同时为“1”,否则为“0”。
此时,
中最大的数便是
和
的最长公共子序列的长度,依据该数组回溯,便可找出最长公共子序列。
该算法的空间、时间复杂度均为
,经过优化后,空间复杂度可为
,时间复杂度为
。
代码 [编辑]
int longest_common_subsequence_length ( int * begin, int * end ) { int n = end - begin; int * temp = new int[n]; int used = 0; for(int i = 0; i < n; ++ i) { int * p = std::lower_bound(temp + 0, temp + used, begin[i]); * p = begin[i]; // insert at `end' if(p == temp + used) { ++ used; } } delete [] temp; return used; }
![f[1][1] = same(1,1)](http://upload.wikimedia.org/math/5/4/4/544a258e4af2b4a4d2a075dabc35d002.png)
![f[i][j] = max\{f[i-1][j-1] + same(i,j), f[i-1][j],f[i][j-1]\}](http://upload.wikimedia.org/math/6/0/5/6059fb703e7e52232639bf370095e549.png)