最长公共字串(非连续)
最长公共字串(非连续)
先考虑二维,复杂度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; }