В интервью я встретил интересный вопрос с алгоритмом. Я дал свой ответ, но не уверен, есть ли какая-то лучшая идея. Поэтому я приветствую всех, кто что-то написал о своих идеях.
У вас есть пустой набор. Теперь элементы помещаются в набор один за другим. Мы предполагаем, что все элементы являются целыми числами, и они различны (в соответствии с определением множества мы не рассматриваем два элемента с одинаковым значением).
Каждый раз, когда в набор добавляется новый элемент, задается заданное медианное значение. Среднее значение определяется так же, как и в математике: средний элемент в отсортированном списке. Здесь, особенно, когда размер множества четный, если предположить размер множества = 2 * x, медианный элемент является x-м элементом множества.
Пример: Начните с пустого набора, когда добавляется 12, медиана равна 12, при добавлении 7 медиана равна 7, когда добавляется 8, медиана равна 8, когда добавляется 11, медиана равна 8, при добавлении 5 медиана равна 8, когда добавляется 16, медиана равна 8, ...
Обратите внимание, что, во-первых, элементы добавляются, чтобы установить один на один и второй, мы не знаем, какие элементы будут добавлены.
Мой ответ.
Поскольку речь идет о поиске медианного, нужна сортировка. Самое простое решение - использовать обычный массив и отсортировать массив. Когда появляется новый элемент, используйте двоичный поиск, чтобы найти позицию для элемента (log_n) и добавить элемент в массив. Так как это нормальный массив, поэтому требуется смещение остальной части массива, чья временная сложность равна n. Когда элемент вставлен, мы можем сразу получить медиану, используя время экземпляра.
ПОСЛЕДНЯЯ временная сложность: log_n + n + 1.
Другим решением является использование списка ссылок. Причина использования списка ссылок заключается в том, чтобы удалить необходимость в переносе массива. Но для нахождения местоположения нового элемента требуется линейный поиск. Добавление элемента занимает мгновенное время, а затем нам нужно найти медиану, пройдя половину массива, которая всегда занимает n/2 раза.
ПОСЛЕДНЯЯ временная сложность: n + 1 + n/2.
Третье решение - использовать двоичное дерево поиска. Используя дерево, мы избегаем смещения массива. Но использование двоичного дерева поиска для поиска медианы не очень привлекательно. Поэтому я изменяю дерево двоичного поиска так, чтобы всегда было сбалансировано левое поддерево и правое поддерево. Это означает, что в любое время либо левое поддерево, и правое поддерево имеют одинаковое количество узлов, либо правое поддерево имеет один node больше, чем в левом поддереве. Другими словами, обеспечивается, что в любой момент корневой элемент является медианным. Конечно, это требует изменений в способе построения дерева. Техническая деталь похожа на вращение красно-черного дерева.
Если дерево поддерживается должным образом, гарантируется, что сложность времени WORST равна O (n).
Таким образом, три алгоритма линейны по размеру набора. Если не существует сублинейного алгоритма, три алгоритма можно рассматривать как оптимальные решения. Поскольку они не сильно отличаются друг от друга, лучше всего проще всего реализовать, что является вторым, используя список ссылок.
Так что я действительно задаюсь вопросом, будет ли сублинейный алгоритм для этой проблемы, и если да, то каково это будет. Любые идеи парней?
Steve.