Базовый алгоритм Hashtable-удаление дубликатов
сегодня утром у меня было интервью, и мне задали вопрос "дайте алгоритм удаления дубликатов из списка целых чисел". Это довольно стандартный вопрос, поэтому я был уверен, что смогу ответить на него.
я перефразирую, но я сказал что-то вроде "Вы могли бы использовать хэш-таблицу. Начните с первого целого числа и вставьте его в hashtable. Затем для каждого последующего целого числа выполните поиск hashtable, чтобы проверить, находится ли целое число уже в hashtable, если нет, то вставьте его, если он уже есть, затем выбросьте его, потому что это дубликат. Итак, повторите список таким образом. Если хэш-таблица разработана правильно, поиск и вставки должны быть в среднем постоянным временем."
затем интервьюер ответил (я перефразирую) ", но хеш-поиска не являются постоянными, они зависят от того, сколько элементов уже в нем. Алгоритм, который вы описали, будет O (n^2)"
затем я ответил "На самом деле? Я думал, что если вы разработаете хорошую хэш-функцию, это будет постоянное время? Делая его O (n) типично"
затем интервьюер ответил: "Итак, вы говорите, что время поиска будет одинаковым для хэш-таблицы со многими записями и хэш-таблицы с несколькими записями"
затем я сказал: "Да. Если он спроектирован правильно."
тогда интервьюер сказал:"Это неправда"
Так что я очень смущен прямо сейчас. Если кто-то может указать где я ошибаюсь, Я был бы очень благодарен
1 ответов
если кто-то может указать, где я ошибаюсь
вы не ошибаетесь: правильно разработанные хэш-таблицы дают вам ожидаемую эффективность поиска O(1)
и вставляет в амортизированном O(1)
, таким образом, ваш алгоритм O(N)
. Поиск в сильно загруженных хэш-таблицах действительно немного медленнее из-за возможного дублирования разрешения, но ожидаемое время поиска остается O(1)
. Это может быть недостаточно хорошо для систем реального времени, где "амортизированные" не граф, но во всех практических ситуациях этого достаточно.
конечно, вы всегда можете использовать сбалансированное дерево для элементов, которые вы видели в худшем случае O(N*LogN)
алгоритм, или если числа имеют разумные границы (скажем, от 0 до 100 000), вы можете использовать логический массив для проверки членства в O(1)
в худшем случае и потенциальное улучшение по сравнению с хэш-таблицей из-за меньшего постоянного множителя.