Однажды я дал интервью «одной известной компании», и интервьюер попросил меня найти медианное значение BST.

int median(treeNode* root)
{

}

Я начал внедрять первое из предложенных мной решений методом перебора. Я заполняю все данные в std::vector<int> с обходом по порядку (чтобы все отсортировано в векторе) и получил средний элемент. Итак, мой алгоритм - O (N) для вставки каждого элемента в вектор и запроса среднего элемента с O (1), + O (N) памяти. Есть ли более эффективный способ (с точки зрения памяти или сложности) сделать то же самое?
Заранее спасибо.

1
Eduard Rostomyan 10 Мар 2015 в 14:58

3 ответа

Лучший ответ

Это можно сделать во времени O(n) и пространстве O(logN), выполнив обход по порядку и остановившись, когда вы достигнете n/2 -го узла, просто неся счетчик, который показывает, сколько узлов имеет уже пройдены - нет необходимости заполнять какой-либо вектор.

Если вы можете изменить свое дерево на ранговое дерево (каждый узел также имеет информацию о количестве узлов в поддереве, корнем которого он является), вы можете легко решить его за время O (logN), просто перемещаясь в направлении n. / 2 элемента.

6
amit 10 Мар 2015 в 12:12

Двоичное дерево предлагает отсортированное представление для ваших данных, но для того, чтобы воспользоваться им, вам нужно знать, сколько элементов находится в каждом поддереве. Итак, без этих знаний ваш алгоритм будет достаточно быстрым.

Если вам известен размер каждого поддерева, вы выбираете каждый раз для посещения левого или правого поддерева, и это дает алгоритм O(log n), если двоичное дерево сбалансировано.

1
JuniorCompressor 10 Мар 2015 в 12:23

Поскольку вы знаете, что медиана - это средний элемент отсортированного списка элементов, вы можете просто взять средний элемент обхода по порядку и остановиться на нем, не сохраняя значения в векторе. Вам может потребоваться два обхода, если вы не знаете количество узлов, но это заставит решение использовать меньше памяти (O(h), где h - высота вашего дерева; h = O(log n) для сбалансированные деревья поиска).

Если вы можете увеличить дерево, вы можете использовать решение, которое я дал здесь, чтобы получить алгоритм O(log n).

1
Community 23 Май 2017 в 12:33