Мне нужно написать RandomQueue, который позволяет добавлять и случайное удаление в постоянное время (O (1)).
Моей первой мыслью было подкрепить его каким-нибудь массивом (я выбрал ArrayList), поскольку массивы имеют постоянный доступ через индекс.
Просматривая документацию, я понял, что добавления ArrayLists считаются амортизированным постоянным временем, поскольку для добавления может потребоваться перераспределение базового массива, который равен O (n).
Являются ли амортизированные постоянное время и постоянное время практически одинаковыми, или мне нужно взглянуть на структуру, которая не требует полного перераспределения при каждом добавлении?
Я спрашиваю об этом, потому что за исключением структур на основе массива (которые, насколько я знаю, всегда будут дополнения Amortized Constant Time), я не могу придумать ничего, что будет соответствовать требованиям:
- Все, что основано на дереве, будет в лучшем случае иметь доступ O (log n)
- Связанный список может потенциально иметь O (1) дополнений (если сохраняется ссылка на хвост), но случайное удаление должно быть в лучшем случае O (n).
Вот полный вопрос; на случай, если я застеклю некоторые важные детали:
Разработка и внедрение RandomQueue. Это реализация интерфейса очереди, в котором операция remove () удаляет элемент, который выбран случайным образом равномерно среди всех элементов, находящихся в данный момент в очереди. (Подумайте о RandomQueue как о сумке, в которую мы можем добавить элементы или достучаться и слепо удалить некоторый случайный элемент.) Операции add (x) и remove () в RandomQueue должны выполняться в постоянном времени для каждой операции.
1/a
шанс для операции O (n)), но прирост по постоянному коэффициенту a > 1
равен O (1), амортизируемому для сложения: у нас есть (1/a)^n
шанс O (n) операция, но эта вероятность приближается к нулю для больших n
.