Jest asymptotycznie szybszy sposób, aby rozwiązać ten problem, ale mam poważne wątpliwości co do tego, czy będzie to działać szybciej w praktyce z powodu swojej wielkości okna (10) jest tak mały.Jeśli chcesz zwiększyć ten rozmiar - który nazywam k - by być większy, możesz rozważyć wybór takiego podejścia, jak poniżej.
Kiedy używasz tego algorytmu, trzeba utrzymać okno elementów k, który obsługuje dwie operacje:
- wstawić nowy element, eksmisji najstarszych.
- Zwraca wszystkie elementy większe niż pewna wartość.
Jednym ze sposobów na zrobienie tego będzie przechowywanie wszystkich elementów w strukturze danych łączącej zrównoważone drzewo wyszukiwania binarnego i kolejkę. Kolejka zawiera wszystkie k elementów zapisanych w kolejności, w jakiej pojawiają się w oryginalnej sekwencji, i jest używana tak, abyśmy pamiętali, który element należy eksmitować, kiedy musimy dodać nowy element. Zrównoważony BST przechowuje kopię każdego z tych elementów przechowywanych w posortowanej kolejności. Oznacza to, że można wdrożyć powyższe operacje takie jak to:
- Włóż nowy element, eksmisji najstarszą: Dodaj nowy element do kolejki i BST. Następnie usuń kolejkę z kolejki, aby uzyskać najstarszy element, a następnie usuń go z BST. Runtime: O (log k), ponieważ BST zawiera k elementów.
- Zwróć wszystkie elementy większe niż pewną wartość: Za pomocą BST znajdź najmniejszy element co najmniej tak duży jak ten w czasie O (log n). Następnie zeskanuj przez BST i wypisz wszystkie elementy co najmniej tak duże jak ten element. Zajmuje to czas O (z), gdzie z jest całkowitą liczbą znalezionych dopasowań.
Łącznie, jeśli masz n elementów i łącznie par z, które musisz wstawić do bazy danych, algorytm ten zajmie czas O (n log k + z). Aby to zobaczyć, pamiętaj, że wykonujemy w sumie n kopii operacji (1), która zajmuje każdy czas O (log k). Wykonujemy również n kopii operacji (2), która zajmuje O (n log k) czas, aby znaleźć następców, a następnie O (z) całkowity czas we wszystkich iteracjach, aby wyświetlić listę wszystkich pasujących par.
Asymptotyczne środowisko wykonawcze tego algorytmu jest dobre w porównaniu z pierwotnie opublikowanym algorytmem O (nk). Zakładając, że liczba dopasowań nie jest "naprawdę ogromna" (powiedzmy, w kolejności nk), będzie to znacznie szybsze, gdy zwiększysz n i k.
Jeśli wartości, które przechowujesz, są liczbami całkowitymi w małym zakresie (powiedzmy 0-10 000), możesz przyspieszyć to jeszcze bardziej, zastępując zrównoważony BST strukturą danych zoptymalizowaną dla liczb całkowitych, taką jak van Emde Boas tree, która zmniejsza to do O (n log log k + z). Ponownie, jest to tylko szybsze asymptotycznie, a jeśli trzymasz k stałej 10, to prawie na pewno nie jest tego warte.
Mam nadzieję, że to pomoże!
Nie widzę, jak na początku jest to O (n^2). Przeszukujesz każdy element tablicy, a następnie przeglądasz 10 elementów. Tak więc to jest imo (10 * N) = O (N), więc w najlepszym przypadku można zmniejszyć stałe obciążenie - ale prawdopodobnie nie przyniesie to znacznych ulepszeń, jeśli nie ma żadnego zamówienia lub czegoś w danych – Voo
Czy dane wartości w dowolnej kolejności? –
Zgadzam się z Voo. Patrzysz na ustaloną odległość z wyprzedzeniem, niezależnie od N, więc nawet jeśli wykonujesz tę samą pracę kilka razy, to po prostu multiplikatywne stałe czasy N więcej pracy, więc twoja pętla to O (N). –