最长公共字串(非连续)

最长公共字串(非连续)
先考虑二维,复杂度O(n*m),但是空间复杂度太高了,n如果>100000就憨脸了。
a[i][j]=a[i-1][j-1]+1(s[i]==s[j]),max(a[i-1][j],a[i][j-1]);
降低空间复杂度,考虑使用滚动数组。
从转移方程中可以看出,只会用到a[i-1][j-1],a[i-1][j],a[i][j-1]。现在考虑一个问题,a[i-1][j-1]在计算a[i][j-1]时会被覆盖掉,那我们只要在赋值之前先记录下来就好了。
时间O(n*m),空间O(n)

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<cstring>
#define inf 2147483647
#define For(i,a,b) for(register int i=a;i<=b;i++)
#define p(a) putchar(a)
#define g() getchar()
//by war
//2017.10.17
using namespace std;
int n,m;
char s1[10010],s2[10010];
int a[10010];
int temp,k;
void in(int &x)
{
    int y=1;
    char c=g();x=0;
    while(c<'0'||c>'9')
    {
    if(c=='-')
    y=-1;
    c=g();
    }
    while(c<='9'&&c>='0')x=x*10+c-'0',c=g();
    x*=y;
}
void o(int x)
{
    if(x<0)
    {
        p('-');
        x=-x;
    }
    if(x>9)o(x/10);
    p(x%10+'0');
}
int main()
{
    cin>>s1>>s2;
    n=strlen(s1);
    m=strlen(s2);
    For(i,0,n-1)
      {
          k=0;
          For(j,0,m-1)
        {
            temp=a[j];
            if(s1[i]==s2[j])
            a[j]=k+1;
            else
            a[j]=max(a[j],a[j-1]);
            k=temp;
        }
      }
    o(a[m-1]);
     return 0;
}
原文地址:https://www.cnblogs.com/war1111/p/7680740.html