У меня есть большой массив/список из 1 миллиона идентификаторов, а затем мне нужно найти первый бесплатный идентификатор, который можно использовать. Можно предположить, что существуют пара модулей, которые относятся к этой структуре данных и принимают идентификатор (в течение которого он должен быть помечен как использованный), а затем возвращать его позже (должен быть отмечен как свободный). Я хочу знать, какие различные структуры данных можно использовать? и какой алгоритм я могу использовать для эффективного использования времени и пространства (отдельно). Пожалуйста, извините, если он уже присутствовал здесь, я выполнил поиск перед публикацией.Поиск первого бесплатного индекса
ответ
Наивным, но эффективным методом было бы хранить все ваши идентификаторы в стеке. Получение идентификатора - операция с постоянным временем: поп первый элемент списка. Когда задача завершена, просто нажмите идентификатор в стеке.
Если минимальный бесплатный идентификатор должен быть возвращен (а не какой-либо свободный идентификатор), вы можете использовать кучу минут с вставкой и поп-позицию в O (log N).
Не стоит ли повторно вставлять ID O (n), так как вам нужно сканировать стек, чтобы найти нужное место? – templatetypedef
@templatetypedef Нет, это должно быть постоянное время, так как все идентификаторы в списке должны быть бесплатными. Просто вставить сверху. – log0
О, я думаю, мы интерпретируем вопрос по-другому. Я думал, что «во-первых» OP означает «самый низкий», тогда как вы интерпретируете его как «все, что бесплатно». В этом случае это отличный ответ! – templatetypedef
Ну, массив, вероятно, не лучшая структура. Хеш был бы лучше, по крайней мере, по скорости. Что касается структуры для каждого «узла», все, что я вижу, что вам нужно, это всего лишь идентификатор, и он используется, или нет.
Как бы вы отслеживали следующий свободный идентификационный номер? – templatetypedef
Одна из исходных идей, которая могла бы работать, заключалась в том, чтобы сохранить очередь приоритетов для всех неиспользуемых идентификаторов, отсортированную так, чтобы низкие идентификаторы были вычеркнуты перед высокими идентификаторами. Используя стандартную двоичную кучу, это позволит вернуть идентификатор в неиспользуемый пул идентификаторов в O (log n) и найти следующий свободный идентификатор в O (log n). Это имеет тот недостаток, что для этого требуется явно хранить все идентификаторы, которые могут быть неэффективными в пространстве, если существует огромное количество идентификаторов.
Одной из возможных задач экономии пространства было бы попытаться объединить последовательные идентификационные значения в диапазоны идентификаторов. Например, если у вас есть бесплатные идентификаторы 1, 3, 4, 5, 6, 8, 9, 10 и 12, вы можете просто сохранить диапазоны 1, 3-6, 8-10 и 12. Это потребует от вас немного изменить базовую структуру данных. Вместо использования двоичной кучи можно использовать сбалансированное двоичное дерево поиска, в котором хранятся диапазоны. Поскольку эти диапазоны не будут перекрываться, вы можете сравнить диапазоны как меньше, равно или больше других диапазонов. Поскольку BST хранятся в отсортированном порядке, вы можете найти первый бесплатный идентификатор, взяв минимальный элемент дерева (в O (log n)) и глядя на нижний конец своего диапазона. Затем вы обновите диапазон, чтобы исключить этот первый элемент, который может потребовать удаления пустого диапазона из дерева. При возврате идентификатора в пул неиспользуемых идентификаторов вы можете выполнить поиск предшественника и преемника, чтобы определить диапазоны, которые поступают непосредственно перед и после ID. Если один из них может быть расширен, чтобы включить этот идентификатор, вы можете просто расширить диапазон. (Возможно, вам потребуется объединить два диапазона). Это также занимает только время O (log n).
Надеюсь, это поможет!
Это та же идея, что и объект последовательности в базе данных. Это работает хорошо. –
Благодарим за подробное описание, мне нужно реализовать описанный вами подход, поскольку другие подходы до дерева Fenley, чтобы увидеть, какой из них можно выполнить с наименьшей сложностью/пространством/временем. –
Попробуйте использовать связанный список (связанный список идентификаторов). Связывание всех этих списков, и голова должна указывать на свободный список (скажем, в init все бесплатны). Всякий раз, когда он будет отмечен как использованный, удалите его и поместите в конце списка и сделайте головной пункт в следующий свободный список. Таким образом, ваш список будет структурирован в виде «от свободного до использования». Вы также можете получить бесплатный список в O (1). Кроме того, когда идентификатор отмечен как бесплатный - поставьте его как первый член связанного списка (поскольку он станет бесплатным, он станет полезным), то есть сделайте головной пункт для этого списка. Надеюсь, это поможет!
Преамбула: бинарная куча кажется лучшим ответом. Я приведу здесь альтернативу, которая может иметь преимущества в некоторых сценариях.
Один из возможных способов - использовать Fenwick Tree. Вы можете хранить в каждой позиции либо 0, либо 1, указывая, что позиция уже использовалась или нет. И вы можете найти первую пустую позицию с бинарным поиском (чтобы найти первый диапазон [1..n], который имеет сумму n-1).Сложность этой операции O (журнал^2 п), что хуже, чем в двоичной куче, но этот подход имеет еще преимущества:
- Вы можете реализовать Фенвик дерево менее чем 10 строк кода
- Теперь можно рассчитать плотность (количество используемых/всего идентификаторов) в диапазоне в O (журнал N)
Если вы не строго нужен низкий идентификатор, вы можете выделить идентификаторы для модулей в партиях по 1000. При освобождении идентификаторов их можно добавить в конец списка. И время от времени вы сортируете список, чтобы снова убедиться, что идентификаторы, которые вы назначили, находятся на нижнем конце.
- 1. Поиск 1-го бесплатного «индекса» с использованием потоков java
- 2. Поиск первого индекса самой длинной повторяющейся последовательности
- 3. Поиск значения индекса индекса
- 4. Получение первого индекса объекта
- 5. Поиск первого индекса элемента, который соответствует условию с использованием LINQ
- 6. Python - Поиск индекса первого непустого элемента в списке
- 7. numpy: поиск первого и последнего индекса в массиве
- 8. Поиск первого индекса в массиве массивов с Javascript
- 9. vb. чистый поиск о предложении и возвращении индекса первого слова
- 10. Поиск индекса первого элемента списка в другом списке
- 11. Нахождение первого индекса первого вхождения цифр
- 12. Поиск адреса с помощью бесплатного текстового поля
- 13. Поиск индекса скрытого индекса V8
- 14. Перестановка из первого индекса массива
- 15. Возврат первого индекса заданного массива
- 16. усложнять толчок массив первого индекса
- 17. Обнаружение первого немого индекса образца
- 18. Поиск индекса символов в строке
- 19. Поиск Solr игнорирование первого слова
- 20. глубины первого поиск
- 21. Поиск первого дня календаря
- 22. Поиск первого порядка поиска
- 23. Поиск индекса в ArrayList
- 24. Поиск последнего индекса массива
- 25. Поиск нужного индекса Splunk
- 26. Поиск индекса массива MongoDB
- 27. Поиск почтового индекса
- 28. Поиск почтового индекса
- 29. Поиск индекса в ArrayList
- 30. Поиск индекса многомерного массива?
Что в первую очередь означает в этом контексте? Вам просто нужен бесплатный идентификатор или наименьший идентификатор (если есть разумный порядок) или первый в списке идентификаторов? Каждый из них дал бы другое решение. – Joel
Являются ли 1 миллион Id связанными с чем-то конкретным или вам просто нужен уникальный идентификатор? Если вам просто нужны уникальные идентификаторы, они представляют собой библиотеки, которые могут генерировать уникальный ориентир по требованию с вероятностью 0 коллизий, предполагая некоторые разумные условия. – log0