一、题目
1、来源
力扣题号1143:https://leetcode-cn.com/problems/longest-common-subsequence/
2、题目描述
给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。
若这两个字符串没有公共子序列,则返回 0。
二、解题思路
1、dp定义
这是一个二维DP问题,需要求解的是两个字符串最长公共子序列的长度,一般我们是可以直接将dp[i][j]
定义为题目求解的答案(也有部分情况还需要对dp进行处理),所以这里我们定义dp[i][j]
为字符串text1[0...i]
与字符串text2[0...j]
的最长公共子序列
2、初始状态
两个字符串分别为text1
与text2
,假设text1="abc",text2="de"
,则dp
形如:
行为text1,列为text2 | “” | d | e |
---|---|---|---|
“” | |||
a | |||
b | |||
c |
两个空串分别表示text1
为空和text2
为空。
(1) 当text1
为空时,text2
的任意一个字符与text1的公共子序列都为空,即dp[0][j]=0, j>=0 && j<=text2.size()
,j
取等号是因为我们表格中考虑了空串,所以dp
的行为text1.size()+1
,列为text2.size()+1
(2) 当text2
为空时,有dp[i][0]=0, i>=0 && i<=text1.size()
,理由同上
3、转移方程
(1) 当text1[i]=text2[j]
时,则有dp[i][j]=dp[i-1][j-1]+1
:
text1 | a | b | ... | c | d | text1(i) |
text2 | d | b | ... | c | d | text2(j) |
可以看到text1[i]
与text2[j]
的最长公共子序列为text1[i-1]
与text2[j-1]
的最长公共子序列+text1[i]或text2[j]
。
(2)当text1[i]!=text2[j]
时,则分为三种情况:
①通过text1[i-1]
与text2[j-1]
计算,即dp[i][j]=dp[i-1][j-1]
text1 | a | b | ... | c | d | text1(i) |
text2 | d | b | ... | c | d | text2(j) |
②通过text1[i-1]
与text2[j]
计算,即dp[i][j]=dp[i-1][j]
text1 | a | b | ... | c | d | text1(i) |
text2 | d | b | ... | c | d | text2(j) |
③通过text1[i]
与text2[j-1]
计算,即dp[i][j]=dp[i][j-1]
text1 | a | b | ... | c | d | text1(i) |
text2 | d | b | ... | c | d | text2(j) |
从上面三种情况可以看到,(text1[i-1],text2[j-1])
的最长公共子序列不可能比(text1[i-1],text2[j])
或者(text1[i],text2[j-1])
的长。所以dp[i][j]=max(dp[i-1][j],dp[i][j-1])
三、C++源码
int longestCommonSubsequence(string text1, string text2) {
int len1=text1.size();
int len2=text2.size();
int dp[len1+1][len2+1]={0}; // 行为text1的长度
for(int i=0;i<=len1;i++) // 类比text2为空串的情况(即列为空串)
dp[i][0]=0;
for(int j=0;j<=len2;j++) // 类型text1为空串的情况,即行为空串
dp[0][j]=0;
for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){ // 将text1的每个字符逐个与text2比较
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]); // dp[i-1][j-1]的长度始终比这两个短
}
}
return dp[len1][len2];
}
来源:CSDN
作者:甜甜的甜甜
链接:https://blog.csdn.net/qq_33742119/article/details/104541319