Przeformułowmy problem: znajdziemy dwa elementy, takie jak abs(x-y) <= c
, gdzie c
jest stałą, którą możemy znaleźć w czasie O(n)
. (Rzeczywiście, możemy obliczyć zarówno max(A)
i min(A)
w czasie liniowym i po prostu przypisać c=(max-min)/n
).
Wyobraźmy sobie, że mamy zestaw wiader, tak, że w pierwszych elementów kubełkowych 0<=x<c
umieszczonych w drugich elementów kubełkowych c<=x<=2c
umieszczonych itp dla każdego elementu, możemy określić jego wiadro do O(1)
czasie. Pamiętaj, że liczba zajętych segmentów nie będzie większa niż liczba elementów w tablicy.
Wykonajmy iterację w tablicy i umieść każdy element w wiadrze. Jeśli w wiadrze będziemy je umieszczać, już jest inny element, to właśnie znaleźliśmy odpowiednią parę x
i y
!
Jeśli wykonaliśmy iterację całej tablicy, a każdy element wpadł do jej własnego wiadra, nie martw się! Iteruj teraz kubły (nie ma więcej niż n
kubełków, jak już powiedzieliśmy powyżej) i dla każdego elementu pojemnika x
, jeśli w następnym wiadrze y
element jest taki, że abs(x-y)<=c
, to znaleźliśmy rozwiązanie.
Jeśli przeszukaliśmy wszystkie wiadra i nie znaleźliśmy odpowiednich elementów, to nie ma rozwiązania.
OMG, naprawdę tęskniłem za tymi rzeczami (zobacz the other answer).
Wiadra mogą być zaimplementowane jako mapa skrótów, gdzie każdy pojemnik ma jeden indeks tablicy (umieszczenie elementu w wiadrze będzie wyglądać tak: buckets[ a[i]/c] = i
). Obliczamy czas c
w czasie O(n)
, przypisujemy elementy do segmentów w czasie O(n)*O(1)
(O(1)
jest dostęp do mapy skrótu), przechodzimy do wiader w czasie O(n)
. Dlatego cały algorytm jest liniowy.
Interesujące i bardzo różniące się od większości zadań domowych tutaj. Chociaż i ja nie mogę wymyślić pomysłu :-( – Joey
Czy w tablicy są duplikaty, a wartości są rzadkie lub gęste? –