题目描述
给定两个字符串A和B,返回两个字符串的最长公共子序列的长度。
例如,A="1A2C3D4B56",B="B1D23CA45B6A","123456"或者"12C4B6"都是最长公共子序列。
给定两个字符串A和B,同时给定两个串的长度n和m,请返回最长公共子序列的长度。
求解过程
设给定的str1的长度为N,str2的长度为M.生成一个N*M的矩阵dp
dp[i][j]的含义为,str1的 子串0-i与str2的自串0-j的最长公共子序列.
对于矩阵第一行来说,即dp[0][i]来说,代表Str1[0]与str2[0-i]的最长公共子序列.若,str1[0]==str2[M],0<=M<=i则 M-I的值都为1.同理对于第一列也是如此.
对于其他情况分以下三种情况讨论
1.dp[i][j] = dp[i-1][j];
例如 A1BC2 AB34C dp[3][4] = 3;dp[4][4]=3
2.dp[i][j] = dp[i][j-1];
例如AB34C A1BC2
3.dp[i][j] = dp[i-1][j-1];
这种情况的发生的前提为 str1[i] == str2[j];
例如 ABCD,ABCD
综上所述,dp[i][j]的值为三者中最大的.
代码实现
class LCS
{
public:
int findLCS(string A, int n, string B, int m)
{
vector<vector<int> >dp(n, vector<int>(m, 0));
bool flag = false;
for (int i=0;i<m; ++i)
{
if(flag)
dp[0][i]=1;
else if(A[0]==B[i])
{
dp[0][i] = 1;
flag = true;
}
}
flag = false;
for (int i=0; i<n; ++i)
{
if(flag)
dp[i][0]=1;
else if(A[i]==B[0])
{
dp[i][0] = 1;
flag = true;
}
}
for (int i=1; i<n; ++i)
{
for (int j=1; j<m; ++j)
{
int onecase = dp[i-1][j];
int twocase = dp[i][j-1];
int threecase=0;
if(A[i] == B[j])
threecase = dp[i-1][j-1]+1;
dp[i][j] = max(max(onecase, twocase), threecase);
}
}
return dp[n-1][m-1];
}
};