继上一篇求解两个字符串最大子串之后,本篇求解两个字符串最大子序列,上一篇链接如下:
https://blog.csdn.net/qq_44509304/article/details/105257424
子序列与子串的区别在于,子序列可以不连续,如'ABGRFOH'的子序列可以为'BFH'。
该问题是比较典型的动态规划题,可以分解最优子结构求解,也是leetcode第1143道题目,leetcode链接如下
https://leetcode-cn.com/problems/longest-common-subsequence/submissions/
用 dp[i][j] 记录长度为 i 的字符串str1与长度为 j 的字符串str2的最大公共子序列长度。可知,若i=0或j=0,dp[0][j]或dp[i][0]为0。当str1[i]=str2[j]时,dp[i][j]=dp[i-1][j-1]+1;否则,dp[i][j]=max(dp[i-1][j],dp[i][j-1])。
编写程序时要注意一些细节,如循环的范围等。
推荐两个写的很好的博主的文章,他们还补充了如何输出最大公共子序列,与最大公共子串问题类似,最大公共子序列不唯一,但最大公共子序列长度是唯一的。都是C++版本的
这个博主写的非常之详细易懂,他只输出了一种最大公共子序列,转附链接如下:
https://blog.csdn.net/weixin_40673608/article/details/84262695
下面另一个博主写了输出所有最大公共子序列的方法和程序,链接如下:
https://blog.csdn.net/u013074465/article/details/45392687
知乎一个还不错的帖子,内有JAVA版本
https://zhuanlan.zhihu.com/p/68409952
我的程序(C++)
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
int l1=text1.length(),l2=text2.length();
int dp[l1+1][l2+1];
if(l1==0||l2==0) return 0;
for(int i=0;i<=l1;i++)
dp[i][0]=0;
for(int j=0;j<=l2;j++)
dp[0][j]=0;
for(int i=1;i<=l1;i++)
{
for(int j=1;j<=l2;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[l1][l2];
}
};