📅  最后修改于: 2023-12-03 14:56:03.031000             🧑  作者: Mango
在两个或多个字符串中,最长公共子序列指的是所有字符串都拥有的最长的子序列,该子序列可以不连续,但其字符在各个字符串中的相对顺序必须保持一致。
现在,我们需要解决的问题是,找到两个字符串中没有重复字符的最长公共子序列。
例如,字符串S1="AGGTAB",字符串S2="GXTXAYB",则该问题的解是字符串“GTAB”。
该问题可以用动态规划的方法解决。首先,我们需要用一个二维数组dp[i][j]来表示S1中前i个字符和S2中前j个字符的没有重复字符的最长公共子序列的长度。然后,我们可以用以下的递推公式来求解:
if (S1[i-1]==S2[j-1] && !used[S1[i-1]])
dp[i][j] = 1 + dp[i-1][j-1];
else
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
其中,used[S1[i-1]]表示字符S1[i-1]是否已经被使用过,如果已经被使用,则不能被作为最长公共子序列的一部分;max函数用来求解两个长度的较大值。
最后,最长公共子序列的长度就是dp[m][n],其中m和n分别是S1和S2的长度。
以下是用C++实现的代码片段:
int lcs(string s1, string s2) {
int m = s1.length(), n = s2.length();
int dp[m + 1][n + 1];
memset(dp, 0, sizeof(dp));
bool used[256] = {false};
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (s1[i - 1] == s2[j - 1] && !used[s1[i - 1]]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
used[s1[i - 1]] = true;
} else {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[m][n];
}
该函数接收两个参数,分别是字符串s1和s2,返回它们的没有重复字符的最长公共子序列的长度。