先来看一看普通的最长公共子序列
给定字符串A和B,求他们的最长公共子序列
DP做法:
设f[i][j]表示A[1~i]和B[1~j]的最长公共子序列的长度
那么f[i][j]=max(f[i-1][j],f[i][j-1])
在上面的基础上,如果A[i]=B[j],则f[i][j]=max(f[i][j],f[i-1][j-1]+1)
代码:
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { dp[i][j]=max(dp[i-1][j],dp[i][j-1]); if(a1[i]==a2[j]) dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1); }
复杂度为O(mn)
那么这道题由于1e5的数据,不论是时间还是空间都会爆炸,就需要考虑另一种做法
我们来观察这个题的特征,发现A和B都是1~n的全排列,也就是说A和B中元素是一样的,考虑充分利用这个特征。
因为最长公共子序列是按位向后比对的,所以a序列某个元素在b序列中的位置如果递增,就说明b中的这个数在a中的这个数整体位置偏后