https://leetcode.com/problems/maximum-binary-tree/solution/
В разделе "Сложность пространства" говорится:
Сложность пространства: O (n). Размер набора может увеличиться до n в худшем случае. В среднем случае размер будет nlogn для n элементов в числах, что дает в среднем сложность для случая O (logn).
Это плохо сформулировано, но верно. Он говорит об объеме памяти, необходимой для построения дерева, а не о количестве памяти, занимаемой самим деревом. Как вы правильно указали, само дерево будет занимать O (n) место, независимо от того, является ли оно сбалансированным или вырожденным.
Рассмотрим массив [1,2,3,4,5,6,7]
. Вы хотите, чтобы корень был наибольшим числом, а слева - все, что находится слева от самого большого числа в массиве. Поскольку массив находится в порядке возрастания, происходит то, что вы извлекаете 7
для корня, а затем делаете рекурсивный вызов для создания левого поддерева. Затем вы извлекаете 6
и делаете еще один рекурсивный вызов для создания левого поддерева этого узла. Вы продолжаете делать рекурсивные звонки, пока не введете 1
. Всего у вас есть шесть вложенных рекурсивных вызовов: O (n).
Теперь посмотрим, что произойдет, если ваш начальный массив будет [1,3,2,7,5,6,4]
. Сначала вы размещаете 7
, а затем делаете рекурсивный вызов с подмассивом [1,3,2]
. Затем вы помещаете 3
и делаете рекурсивный вызов для размещения 1
. Ваше дерево:
7
3
1
На этом этапе глубина вашего вызова равна 2. Вы возвращаетесь и ставите 2
. Затем вернитесь из двух рекурсивных вызовов. Дерево теперь выглядит так:
7
3
1 2
Для построения правильного поддерева также требуется глубина вызова, равная 2. Ни в одной точке глубина вызова не превышает двух. Это O (log n).
Оказывается, глубина стека вызовов равна высоте дерева. Высота идеального дерева - O (log n), а высота вырожденного дерева - O (n).