O (n) zaman / uzay karmaşıklığı için, püf noktası her bir sonraki işlem için karmaları değerlendirmektir. Diziyi düşünün b:
[b1 b2 b3 ... bn]
Horner yöntemini kullanarak , her bir takip için olası tüm karmaları değerlendirebilirsiniz. Bir taban değeri seçin B(her iki dizinizdeki herhangi bir değerden daha büyük):
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
Her sekansı, önceki sekansın sonucunu kullanarak O (1) zamanında değerlendirebildiğinizi, dolayısıyla tüm iş masraflarını O (n) değerlendirebileceğinizi unutmayın.
Şimdi bir diziniz var Hb = [h(b1), h(b2), ... , h(bn)], burası Hb[i]hash b1olana kadar bi.
Dizi için aynı şeyi yapın a, ancak küçük bir hile ile:
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)
Bir diziden diğerine adım attığınızda, önceki dizinin tamamını B ile çarptığınızı ve yeni değeri B ile çarptığınızı not etmelisiniz. Örneğin:
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)
Şimdi bir diziniz var Ha = [h(an), h(an-1), ... , h(a1)], burası Ha[i]hash aiolana kadar an.
Şimdi, n'den 1'e kadar Ha[d] == Hb[d]tüm ddeğerleri karşılaştırabilirsiniz , eğer eşleşirse, cevabınız vardır.
DİKKAT : Bu bir karma yöntemdir, değerler büyük olabilir ve hızlı bir üs alma yöntemi ve modüler aritmetik kullanmanız gerekebilir, bu da size (neredeyse) çarpışmalar verebilir , bu yöntemi tamamen güvenli hale getirmez. İyi bir uygulama, Bgerçekten büyük bir asal sayı olarak bir taban seçmektir (en azından dizilerinizdeki en büyük değerden daha büyük). Ayrıca, her adımda sayıların sınırları taşabileceğinden de dikkatli olmalısınız, bu nedenle Kher işlemde ( modulo ) kullanmanız gerekir (burada Kasal daha büyük olabilir B).
Bu, iki farklı sekansın aynı hash'a sahip olabileceği , ancak iki eşit sekansın her zaman aynı hash'a sahip olacağı anlamına gelir .
b[1] to b[d]ve sonraaeşleşirse dizi hesaplama karma değerine gidin,a[1] to a[d]o zaman bu sizin cevabınızdır, eğer hesaplanan karma değerinia[2] to a[d+1]yeniden kullanarak hesaplama karma değeri değilsea[1] to a[d]. Ama dizideki nesnelerin, üzerinde bir haddeleme karma hesaplamak için uygun olup olmadığını bilmiyorum.