对于O(n)的时间/空间复杂度,诀窍是评估每个子序列的哈希值。考虑数组b:
[b1 b2 b3 ... bn]
使用Horner的方法,您可以评估每个子序列的所有可能哈希值。选择一个基值B(大于两个数组中的任何值):
from b1 to b1 = b1 * B^1
from b1 to b2 = b1 * B^1 + b2 * B^2
from b1 to b3 = b1 * B^1 + b2 * B^2 + b3 * B^3
...
from b1 to bn = b1 * B^1 + b2 * B^2 + b3 * B^3 + ... + bn * B^n
请注意,您可以使用前一个序列的结果来评估O(1)时间中的每个序列,因此所有作业成本为O(n)。
现在您有了一个数组Hb = [h(b1), h(b2), ... , h(bn)],Hb[i]从b1到的哈希值在哪里bi。
对数组执行相同的操作a,但有一点技巧:
from an to an = (an * B^1)
from an-1 to an = (an-1 * B^1) + (an * B^2)
from an-2 to an = (an-2 * B^1) + (an-1 * B^2) + (an * B^3)
...
from a1 to an = (a1 * B^1) + (a2 * B^2) + (a3 * B^3) + ... + (an * B^n)
必须注意的是,当您从一个序列移至另一个序列时,请将整个先前序列乘以B,然后将新值乘以B。例如:
from an to an = (an * B^1)
for the next sequence, multiply the previous by B: (an * B^1) * B = (an * B^2)
now sum with the new value multiplied by B: (an-1 * B^1) + (an * B^2)
hence:
from an-1 to an = (an-1 * B^1) + (an * B^2)
现在您有了一个数组Ha = [h(an), h(an-1), ... , h(a1)],Ha[i]从ai到的哈希值在哪里an。
现在,您可以比较从n到1的Ha[d] == Hb[d]所有d值,如果它们匹配,您将得到答案。
注意:这是一个哈希方法,值可能很大,您可能必须使用快速取幂方法和模块化算术,这可能(几乎)给您带来冲突,从而使此方法并不完全安全。一个好的做法是选择一个底数B作为一个非常大的素数(至少大于数组中的最大值)。您还应该小心,因为数字的限制可能会在每个步骤中溢出,因此您必须K在每个操作中使用(取模)(其中K可能比素数大B)。
这意味着两个不同的序列可能具有相同的哈希,但是两个相等的序列将始终具有相同的哈希。
b[1] to b[d],然后转到数组a计算哈希值(a[1] to a[d]如果匹配),这就是您的答案;如果不计算哈希值,则可以a[2] to a[d+1]通过重新使用为计算得出的哈希值a[1] to a[d]。但是我不知道数组中的对象是否适合在其上计算滚动哈希。