Algorithm 最长公共子序列算法

Algorithm 最长公共子序列算法,algorithm,dynamic-programming,Algorithm,Dynamic Programming,在最长公共子序列(LCS)问题中,为什么要匹配字符串的最后一个字符。前 考虑输入字符串“AgPad”< /C>和“Axtxayb”< /C>。最后一个字符与字符串匹配。因此,LCS的长度可以写成: L(“AGGTAB”, “AXTXAYB”) = 1 + L(“AGGTA”, “AXTXAY”) L(“AGGTAB”, “AXTXAYB”) = 1 + L(“GGTAB”, “XTXAYB”) 如果我们匹配字符串的第一个字符,算法不会仍然产生最佳搜索吗。比如说 考虑输入字符串“AGGTAB”

在最长公共子序列(LCS)问题中,为什么要匹配字符串的最后一个字符。前 考虑输入字符串<代码>“AgPad”< /C>和<代码>“Axtxayb”< /C>。最后一个字符与字符串匹配。因此,LCS的长度可以写成:

L(“AGGTAB”, “AXTXAYB”) = 1 + L(“AGGTA”, “AXTXAY”)
L(“AGGTAB”, “AXTXAYB”) = 1 + L(“GGTAB”, “XTXAYB”)
如果我们匹配字符串的第一个字符,算法不会仍然产生最佳搜索吗。比如说

考虑输入字符串
“AGGTAB”
“AXTXAYB”
。第一个字符与字符串匹配。因此,LCS的长度可以写成:

L(“AGGTAB”, “AXTXAYB”) = 1 + L(“AGGTA”, “AXTXAY”)
L(“AGGTAB”, “AXTXAYB”) = 1 + L(“GGTAB”, “XTXAYB”)

LCS问题:

是的,您可以这样做,但不会改变时间复杂度。从最后一个开始只是惯例。

是的,这是同样的事情

计算两个反转序列的LCS与反转前反转两个序列的LCS相同。换句话说,

REVERSE(LCS(A,B)) = LCS(REVERSE(A), REVERSE(B))
假设
LCS
从一端开始减少,右侧的操作将从另一端开始,但会获得相同的结果

这就是为什么你可以用解释中使用后缀的方法来处理前缀:你会在这个过程中得到同样的递归归约


此外,如果你愿意,你可以在两端做减量。然而,这将使算法复杂化很多,而不会给您带来任何速度。

事实证明,如果我们从上一个开始执行LCS,您可以在用户提供的递归中直接使用长度变量(例如M,N)。另一方面,如果从开始索引创建变量,则必须创建额外的变量。这就是前一种方法被视为标准的原因,否则就没有复杂性差异,一切都是一样的

LCS (M, N)
{
if(M==0 || N==0)
return 0;
elseif (a[M]!=b[N])
return max(LCS(M,N-1), LCS(M-1,N));
else
return 1 + LCS(M-1,N-1);
}

感谢@dasblinkenlight的解释。我看到人们总是使用后缀部分,不知道为什么人们不使用前缀。谢谢@nikhil_vyas的回答