有没有办法在O(NlogN)时间内找到两个序列中最长的公共子序列?
我在某处读到有一种方法可以使用二进制搜索来实现这一点。
我知道采用O(N 2 )时间的dp方法。
答案 0 :(得分:5)
对于一般情况,O(N ^ 2)动态编程算法是您可以做的最好的。但是,在某些特殊情况下存在更好的算法。
这是一种非常常见的情况。由某些字母表中的字母组成的序列(例如英语)属于此类别。对于这种情况,可以优化O(N * M)算法以获得具有method of four Russians的O(N ^ 2 / logN)。我不知道究竟是什么,你可以搜索它。
一个示例问题是“给定从1到N的两个数字排列,找到它们的LCS”。这个可以用O(N * logN)来解决。
让序列为A和B.
定义序列C.C [i]是A中B [i]的索引。(A [C [i]] = B [i])
A和B的LCS是C的longest increasing subsequence。
答案 1 :(得分:3)
O(n 2 )的dynamic programming approach完全是通用的。对于某些其他情况,有较低复杂度的算法:
对于固定的字母大小(不会随着 n 而增长),Method of Four Russians会将时间缩短到 O(n 2 / log n)(见here)。
请参阅here另一个进一步优化的案例。
答案 2 :(得分:1)
两个序列之间最长的共同子序列基本上是n平方。
Masek and Patterson (1980)使用所谓的" Four Russians"对n平方/ log n进行了小幅改进。技术
在大多数情况下,这种错综复杂的方法引入的额外复杂性并不能通过微小的收益来证明。出于实际目的,您可以将n平方法视为典型应用中的合理最优方法。
答案 3 :(得分:1)
假设Exponential Time Hypothesis(比P更严格不等于NP,但仍被广泛认为是真的),则无法在时间O(N ^ {2 - eps})中进行此操作对于任何正的常数eps,请参阅Karl Bringmann和Marvin Kunnemann的"Quadratic Conditional Lower Bounds for String Problems and Dynamic Time Warping"(可在arXiv上预打印)。
粗略地说,这意味着这个问题的一般情况不能比O(N ^ 2 / log N)更好地解决,所以如果你想要更快的算法,你必须考虑额外的约束(某些属性)字符串)或寻找近似解。