动态规划五部曲:
1、确定dp数组及其下标含义
dp[i][j]:text1[0]到text1[i-1]的字符串和text2[0]到text2[j-1]的字符串的最长公共子序列的长度为dp[i][j],不一定要包含text[i-1]和text[j-1] ,这里是和最长递增子序列、最长连续递增序列、最长重复子数组不一样的地方,前面所说的这三个 都要求包含vec[i-1]或者vec[i];因而这里的返回值跟前面都不一样 不需要使用一个值去记录最大值
2、确定递推式
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])
3、初始化
初始化为0
4、遍历顺序
从前往后
5、举例推导dp数组
"abcde"
"ace"
dp数组变化:
0 0 0 0
0 1 1 1
0 1 1 1
0 1 2 2
0 1 2 2
0 1 2 3
题解:
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
//dp[i][j]:text1[0]到text1[i-1]的字符串和text2[0]到text2[j-1]
//的字符串的最长公共子序列的长度为dp[i][j] 不一定要包含text[i-1]和text[j-1]
//确定递推式
//if(text1[i-1] = text2[j-1]) dp[i][j] = dp[i-1][j-1]+1;
//否则 dp[i][j] = max(dp[i-1][j],dp[i][j-1])
//定义dp数组
vector<vector<int>> dp(text1.size()+1,vector<int>(text2.size()+1,0));
//计算dp数组
for(int i = 1;i<=text1.size();i++){
for(int j = 1;j<=text2.size();j++){
if(text1[i-1] == text2[j-1]){
dp[i][j] = dp[i-1][j-1]+1;
}
else{
dp[i][j] = max(dp[i][j-1],dp[i-1][j]);
}
}
}
return dp[text1.size()][text2.size()];
}
};