最长公共子序列LCS

最长公共子序列,典型的动态规划,时间复杂度O(mn),空间复杂度O(mn),

如果只要长度,不要序列,优化时间复杂度O(mn),空间复杂度用两行min(O(m),O(n))

代码如下:

 1 #include <iostream>
 2 using namespace std;
 3 #include <string>
 4 
 5 void lcs(int **A,const string &x,const string &y)
 6 {
 7     int m=x.size();
 8     int n=y.size();
 9     if(m<=0||n<=0)
10         return;
11     for(int i=0;i<=n;i++)           //A[m+1][n+1] 都是从0到m和0到n
12         A[0][i]=0;
13     for(int i=1;i<=m;i++)
14         A[i][0]=0;
15     for(int i=1;i<=m;i++)
16         for(int j=1;j<=n;j++)
17         {
18             if(x[i-1]==y[j-1])            //注意,因为字符串是从0到m-1和0到n-1
19                 A[i][j]=A[i-1][j-1]+1;
20             else
21                 A[i][j]=max(A[i-1][j],A[i][j-1]);
22         }
23 }
24 
25 void print(int **A,int m,int n,const string &x,const string &y)
26 {
27     if(m==0||n==0)
28         return;
29 
30     if(x[m-1]==y[n-1])              //必须用递归,不然是倒序的,从A[m][n]开始向前
31     {
32         print(A,m-1,n-1,x,y);
33         cout<<x[m-1]<<endl;
34     }
35     else if(A[m-1][n]>=A[m][n-1])
36         print(A,m-1,n,x,y);
37     else
38         print(A,m,n-1,x,y);
39 }
40 
41 int main()
42 {
43     string x="abcdefglasfsd";
44     string y="abegsdfa";
45     int m=x.size();
46     int n=y.size();
47     int **A=new int*[m+1];
48     for(int i=0;i<=m;i++)
49         A[i]=new int[n+1];
50     lcs(A,x,y);
51     print(A,m,n,x,y);
52     for(int i=0;i<=m;i++)
53         free(A[i]);
54     free(A);
55     system("PAUSE");
56 }

主要注意下标问题,A[m+1][n+1]和字符数组是0~m-1和0~n-1。

(2)还用中矩阵解法,实在搞不定。

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/zmlctt/p/3838701.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞