Muszę napisać RandomQueue, która pozwala na dołączanie i losowe usuwanie w Constant Time (O (1)).
Moją pierwszą myślą było poparcie go jakimś rodzajem Array (wybrałem ArrayList), ponieważ tablice mają stały dostęp za pośrednictwem indeksu.
Przeglądając dokumentację, zdałem sobie sprawę, że dodatki ArrayLists są uważane za amortyzowane stałe, ponieważ dodanie może wymagać realokacji bazowej tablicy, którą jest O (n).
Czy amortyzowany stały czas i stały czas są faktycznie takie same, czy też muszę przyjrzeć się jakiejś strukturze, która nie wymaga pełnej realokacji przy każdym dodaniu?
Pytam o to, ponieważ poza strukturami opartymi na macierzach (które, o ile mi wiadomo, zawsze będą zawierały zamortyzowane dodatki w czasie stałym), nie mogę wymyślić niczego, co spełni wymagania:
- Wszystko oparte na drzewie będzie miało co najwyżej dostęp O (log n)
- Połączona lista może potencjalnie zawierać dodatki O (1) (jeśli zachowane jest odniesienie do ogona), ale losowe usunięcie powinno być co najwyżej O (n).
Oto pełne pytanie; na wypadek, gdy przeszklę niektóre ważne szczegóły:
Zaprojektuj i zaimplementuj RandomQueue. Jest to implementacja interfejsu kolejki, w której operacja remove () usuwa element losowo wybierany równomiernie spośród wszystkich elementów znajdujących się w kolejce. (Pomyśl o RandomQueue jako o torbie, w której możemy dodawać elementy lub sięgać i ślepo usuwać niektóre losowe elementy.) Operacje add (x) i remove () w RandomQueue powinny działać w stałym czasie na operację.
1/a
szansę na operację O (n)), ale rosnące o stały czynnik a > 1
jest amortyzowane przez O (1) do dodania: mamy (1/a)^n
szansę na O (n) operacja, ale to prawdopodobieństwo zbliża się do zera dla dużej n
.