我需要一个表示一组序列(所有相同,已知,长度)的数据结构,并具有以下非标准操作:
在集合中找到两个恰好在一个索引上不同的序列。 (或确定不存在这样的一对。)
如果N
是序列的长度和M
序列的数量,则有一个明显的O(N*M*M)
算法。我想知道是否有一种更有效地解决这个问题的标准方法。如果需要,我愿意应用预处理。
奖励积分如果不是返回一对,算法会返回所有序列,这些序列在同一点上不同。
或者,我也对一个解决方案感兴趣,我可以有效地检查一个索引处的特定序列是否与集合中的任何序列不同。如果它有帮助,我们可以假设在集合中,没有两个序列具有该属性。
修改:您可以假设N
相当小。通过这种方式,我的意思是O(log(N)*M*M)
等改进对我的用例不会立即有用。
答案 0 :(得分:2)
对于该序列中的每个序列和每个位置i,计算没有位置i的序列的散列并将其添加到散列表中。如果表中已有条目,则表示您找到了一个仅在一个位置不同的潜在货币对。从开始和结束使用rolling hashes并将它们组合起来,您可以在恒定时间内计算每个哈希。总运行时间预计为O(N * M)。
答案 1 :(得分:0)
随机选择j组k个索引(确保没有任何组重叠)。
对于每个集合XOR元素。
现在每个文档都有j个指纹。
根据这些指纹比较序列。如果序列确实匹配,则j-1指纹应该匹配。但反过来可能并非如此,您可能需要按位置检查位置。
对比较部分的更多说明:对所有文档中的所有指纹进行排序(或使用哈希表)。通过这种方式,您不必比较每对,而只需要比较具有匹配指纹的对。
答案 2 :(得分:0)
一种简单的递归方法:
通过排序或散列查找具有相同前半部分的所有序列集。
对于每一套,现在重复整个过程,只看下半部。
通过排序或散列查找具有相同后半部分的所有序列集。
对于每一套,现在重复整个过程,只看上半部分。
当你达到长度1时,所有那些不匹配的就是你要找的东西。
的伪代码:
findPairs(1, N)
findPairs(set, start, end)
mid = (start + end)/2
sort set according to start and mid indices
if end - start == 1
last = ''
for each seq: set
if last != '' and seq != last
DONE - PAIR FOUND
last = seq
else
newSet = {}
last = ''
for each seq: set
if newSet.length > 1 and seq and last don't match from start to mid indices
findPairs(newSet, mid, end)
newSet = {}
newSet += seq
last = seq
修改代码以便能够找到所有对都应该很容易。
复杂性?我可能错了,但是:
最大深度为log M
。 (我相信)最糟糕的情况是如果所有序列都相同。在这种情况下,完成的工作将为O(N*M*log M*log M)
,这比O(N*M*M)
更好。