Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何为最长公共子序列(LCS)的这种特殊情况找到更快的算法?_Algorithm_Computer Science_Dynamic Programming_Lcs - Fatal编程技术网

Algorithm 如何为最长公共子序列(LCS)的这种特殊情况找到更快的算法?

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(

我知道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)一样好的算法,但我不明白

更新: 已经找到答案了


我被告知我可以计算表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噢,是的。这真的很简单!我的解决方案看起来太过分了。