求最长公共子序列(LCS)最最常见的算法是时间复杂度为O(n^2)的动态规划(DP)算法,这种算法在各类算法书上基本都有--DP入门典型问题!
现在,介绍一种求LCS的时间复杂度为O(nlogn)的算法:最长公共子序列(LCS)向最长递增子序列(LIS)退化,如下:设有序列A,B。记序列A中各个元素在B 中的位置(可能有多个,要降序排列),然后,按A中各个元素在B中位置依次列出合并为一个下标数组,最后该数组求最长递增子序列即可。说的可能不是太清楚,看下面的例子就一目了然了:
例如:有A={a,b,a,c,x},B={b,a,a,b,c,a},则有a={6,3,2},b={4,1},c={5};x={};(注意:降序排列),然后,按A中次序排出{a(6,3,2),b(4,1),a(6,3,2),c(5),x()} = { 6,3,2,4,1,6,3,2,5};对此序列求最长递增子序列即可。
其实,假如A的长度为m, B的长度为n,准确的说,算法复杂度下界为:O(nlogn),上界为:O(m*n*log(m*n))。所以,使用时一定要根据具体问题选择是否使用该方法,我遇到的问题两个句子公共的字符不是很多,更加靠近下界。
求最长递增子序列的算法见:最长有序子序列(递增/递减/非递增/非递减)
参考资料:http://www.cs.ucf.edu/courses/cap5937/fall2004/Longest%20common%20subsequence.pdf