Algorithm 如何为最长公共子序列(LCS)的这种特殊情况找到更快的算法?
我知道LCS问题需要时间~O(mn),其中m和n分别是两个序列X和Y的长度。但是我的问题稍微简单一点,所以我希望有一个比~O(mn)更快的算法 我的问题是: 输入: 一个正整数Q,两个序列X=x1,x2,x3…..xn和Y=y1,y2,y3…yn,长度均为n 输出: 如果X和Y的LCS的长度至少为n-Q,则为True 否则就错了 众所周知的算法在这里花费O(n^2),但实际上我们可以做得更好。因为每当我们在两个序列中消除多达Q个元素而没有找到公共元素时,结果返回False。有人说应该有一个和O(Q*n)一样好的算法,但我不明白 更新: 已经找到答案了Algorithm 如何为最长公共子序列(LCS)的这种特殊情况找到更快的算法?,algorithm,computer-science,dynamic-programming,lcs,Algorithm,Computer Science,Dynamic Programming,Lcs,我知道LCS问题需要时间~O(mn),其中m和n分别是两个序列X和Y的长度。但是我的问题稍微简单一点,所以我希望有一个比~O(mn)更快的算法 我的问题是: 输入: 一个正整数Q,两个序列X=x1,x2,x3…..xn和Y=y1,y2,y3…yn,长度均为n 输出: 如果X和Y的LCS的长度至少为n-Q,则为True 否则就错了 众所周知的算法在这里花费O(n^2),但实际上我们可以做得更好。因为每当我们在两个序列中消除多达Q个元素而没有找到公共元素时,结果返回False。有人说应该有一个和O(
我被告知我可以计算表c[I,j]的对角块,因为如果| I-j |>Q,意味着两个序列中已经有超过Q个不匹配的元素。所以我们只需要在| i-j |时计算c[i,j],这里有一种可能的方法:
1.让我们假设
f(prefix_len,deleted_cnt)
是Y
中最左边的位置,这样prefix_len
元素的X
已经被处理,并且其中的deleted_cnt
已经被删除。显然,只有O(N*Q)
状态,因为deleted\u cnt
不能超过Q
2.基本情况是
f(0,0)=0
(未处理任何内容,因此未删除任何内容)。3.过渡:
a) 删除当前元素:
f(i+1,j+1)=min(f(i+1,j+1),f(i,j))
b) 将当前元素与位于
f(i,j)
之后的Y
中最左边的元素相匹配(假设它有索引pos
):f(i+1,j)=min(f(i+1,j),pos)
4.因此,剩下的唯一问题是如何从给定位置获得位于右侧的最左侧匹配元素。让我们预先计算以下几对:(位于
Y
,元素X
)->元素Y
最左边的匹配项等于X
这个元素在Y
的右边,并将它们放入哈希表中。它看起来像O(n^2)
。但事实并非如此。对于Y
中的固定位置,我们永远不需要从它向右移动,而只需要通过Q+1
位置。为什么?如果我们更进一步,我们将跳过超过Q
元素!因此,我们可以使用这个事实只检查O(N*Q)
对,并获得所需的时间复杂度。当我们有这个哈希表时,在步骤3中查找pos
仅仅是一个哈希表查找。以下是此步骤的伪代码:
map = EmptyHashMap()
for i = 0 ... n - 1:
for j = i + 1 ... min(n - 1, i + q + 1)
map[(i, Y[j])] = min(map[(i, Y[j])], j)
不幸的是,此解决方案使用哈希表,因此它的平均时间复杂度为
O(N*Q)
,在最坏的情况下不是这样,但它应该是可行的。您还可以说,使字符串相等的过程成本不得大于Q。如果大于Q,则答案必须为false。(编辑距离问题)
假设字符串x的长度为m,字符串y的大小为n,那么我们创建一个二维数组d[0..m][0..n],其中d[i][j]表示x的i长度前缀和y的j长度前缀之间的编辑距离
数组d的计算使用动态规划完成,动态规划使用以下递归:
d[i][0] = i , for i <= m
d[0][j] = j , for j <= n
d[i][j] = d[i - 1][j - 1], if s[i] == w[j],
d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + 1), otherwise.
d[i][0]=i,对于i,本质上你只需要找到长度n-Q的公共子序列,因此我们知道它必须从第一个Q+1位置之一开始。那一定会有帮助的。谢谢!这个方法很好。然而,有人告诉我,我可以只计算表c[I,j]的对角块,因为如果| I-j |>Q,意味着两个序列中已经有超过Q个不匹配的元素。所以我们只需要计算c[i,j]当| i-j |@ValarMorghulis噢,是的。这真的很简单!我的解决方案看起来太过分了。