问题
序列s的子序列是原序列的子集,元素相对原序列的顺序不变。例如s=[1,2,3]的子序列有
[1,2,3],[1,2],[1,3],[2,3],[1],[2],[3],[] 求两个序列s1和s2的最长公共子序列的长度。
解法
设序列s长度为n(数组从1开始,范围[1,n])。设f(i,j)为s1=[1,i]和s2=[1,j]的最长公共子序列的长度,则有状态转移方程:
f(i,j)=⎩⎨⎧0f(i−1,j−1)+1max(f(i,j−1),f(i−1,j))(initialize)(loop)(loop)i,j∈[0,n]i,j∈[1,n],s1[i]=s2[j]i,j∈[1,n],s1[i]=s2[j] (1) 初始化f(i,j)=0;
(2) 若s1[i]=s2[j],则显然两个序列的这个部分是公共的,所以f(i,j)在f(i−1,j−1)的基础上加1;
(3) 若s1[i]=s2[j],则两个序列的这个部分不是公共的,所以f(i,j)仍然保持之前的值,为了获取最大值我们会在f(i,j−1)和f(i−1,j)中选取最大的那个;
f(n,n)即为序列s1和s2的最长公共子序列的长度值。该算法的时间复杂度为O(n2)。
源码
LongestCommonSubsequence.h
LongestCommonSubsequence.cpp
测试
LongestCommonSubsequenceTest.cpp