思路:动态规划的二维问题。
我们这里并不能仅限于把dp看作就是一维的了。dp也可以是二维的,这里就是一个例子,其实这里以字符为尾的数组,你发现只能对于一个数组进行遍历,而不能同时对于两个数组进行遍历。 这里就需要我们开二维数组进行解决了。
dp[i][j]代表的就是对于text1[i]的[0,i-1]区间与text2[j]的[0,j-1]区间的最长公共子序列的长度。这样就顾及到第二个数组里面的东西了。OK,那么我们开始推状态方程。
假如我们以最后一个字符为尾为例,这个时候,如果说循环遍历到的目前这个i,j字符,text1[i]==text2[j],那么就说明了我们当前遍历到的字符相同,可以是公共序列里面的一个元素,所以在前面已经递推的基础上+1,总体来写也就是dp[i][j]=dp[i-1][j-1]+1.
那如果不相同呢?那我们就开始找前面已经递推过来的状态了,dp[i-1][j]与dp[i][j-1]。为什么需要找这两个呢?我们想,刚刚第一种情况,我们把这两个字符的位置全部倒退了一步,但是在这里我们为什么要分开倒退呢?只倒退第一个,可能当前的字符和第一个字符串倒退后的位置的字符是相同的。同理,如果第二个字符倒退一步,那可能第二个字符串当前指向的字符位置和第一个字符串目前的字符是相同的。
所以,状态方程就成了:
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
int dp[1010][1010];
memset(dp,0,sizeof dp);
int n1=text1.size();
int n2=text2.size();
for(int i=1;i<=n1;i++){
for(int j=1;j<=n2;j++){
if(text1[i-1]==text2[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
return dp[n1][n2];
}
};