Задача: инвертируем бинарное дерево
Решаем задачи, которые дают программистам на собеседованиях в IT-компаниях. Сегодня инвертируем бинарное дерево.
Иллюстрация: Polina Vari для Skillbox Media
Сергей Голицын
Senior Java Developer в Covalent Inc. и преподаватель. Больше семи лет в Java-разработке. В свободное время судит хакатоны и делится опытом с начинающими программистами. Пишет статьи для «Хабра» и Medium. Ведёт телеграм-каналы «Полезные ссылки около Java» и Cracking code interview.
Условие. Дан массив узлов бинарного дерева — root. Нужно инвертировать дерево и вернуть полученный массив. Инвертировать бинарное дерево — значит сделать так, чтобы слева от главного узла были значения больше него, а справа — меньше. Когда значения равны, их можно помещать с любой стороны.
Ввод и вывод. Пример 1
Ввод и вывод. Пример 2
Ввод и вывод. Пример 3
Решить эту задачу самостоятельно и на разных языках программирования можно на LeetCode. Наше решение взято из Telegram-канала Сергея Cracking code interview.
Решение
Чтобы решить эту задачу, мы должны поменять все левые и правые элементы местами и сделать это в обратном порядке — с помощью рекурсии.
Начнём с самого верхнего узла и будем двигаться вниз — до самого нижнего. Каждый раз, когда мы заходим на очередной узел, меняем левый и правый элементы местами. А когда узлы закончатся, возвращаем полученный массив.
Полный алгоритм такой:
- На входе мы получаем узел бинарного дерева — root.
- Проверяем: если root — это пустой массив или null, то возвращаем null.
- Если нет: вызываем рекурсию на левый узел, а затем на правый.
- После того как обе рекурсии вернули результаты, меняем левый и правый узлы местами.
- Возвращаем корень дерева.
Вот как этот алгоритм будет реализован на Java:
Результаты
Временная сложность: O(n) — так как мы перебирали все элементы массива.
Ёмкостная сложность: O(1) — нам нужно заранее определённое количество места в памяти (максимальный размер памяти — размер массива бинарного дерева).