力扣[剑指 Offer II 095. 最长公共子序列]
题目:
思路:
动态规划,定义一个大小为m,nm,nm,n的二维数组
定义dpijdp_{ij}dpij为s1s1s1字符串前iii个字符与s2s2s2字符串前jjj个字符的最长公共子序列
不难发现当i=0∣j=0i=0|j=0i=0∣j=0时,dpi,jdp_{i,j}dpi,j一定等于000
刚好数组初始化所有之都为000,所以我们从i=1,j=1i=1,j=1i=1,j=1开始循环查表
对于每一个dpi,jdp_{i,j}dpi,j它的值都为前面所有可能的状态的最大值
加上当前值:
每个dpi,jdp_{i,j}dpi,j首先判断当前字符加不加 如果s1[i]==s2[j]s1[i]==s2[j]s1[i]==s2[j],那么加上当前的i,ji,ji,j,值应该为
dp[i][j]=dp[i−1][j−1]+1
dp[i][j]=dp[i-1][j-1]+1
dp[i][j]=dp[i−1][j−1]+1
因为我们已经算上了s1[i]==s2[j]s1[i]==s2[j]s1[i]==s2[j]的公共串,并且加一了,所以我们再加上dp[i−1][j−1]dp[i-1][j-1]dp[i−1][j−1]的值就是加当前字符的值
不加上当前值
dp[i][j]=max(dp[i−1][j],dp[i][j−1])
dp[i][j]=max(dp[i-1][j],dp[i][j-1])
dp[i][j]=max(dp[i−1][j],dp[i][j−1])
所以我们只需要对两种状态取最大值就是我们当前dp[i][j]dp[i][j]dp[i][j]的值
dp[i][j]=max(dp[i−1][j−1]+mark,max(dp[i−1][j],dp[i][j−1]))mark为状态位,如果s1[i]==s2[j],那么mark=1,否则mark=0
dp[i][j]=max(dp[i-1][j-1]+mark,max(dp[i-1][j],dp[i][j-1]))\\
mark为状态位,如果s1[i]==s2[j],那么mark=1,否则mark=0
dp[i][j]=max(dp[i−1][j−1]+mark,max(dp[i−1][j],dp[i][j−1]))mark为状态位,如果s1[i]==s2[j],那么mark=1,否则mark=0
代码:
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
int len1=text1.size();
int len2=text2.size();
text1='@'+text1;
text2='@'+text2;//使有效值的下标从1开始
int dp[1010][1010]={0};
for(int i=1;i<=len1;i++){
for(int o=1;o<=len2;o++){
int mark=0;
if(text1[i]==text2[o]){
mark++;
}
dp[i][o]=max(dp[i-1][o-1]+mark,max(dp[i-1][o],dp[i][o-1]));
}
}
return dp[len1][len2];
}
};