Паттерн "сверху вниз"

В паттерне "снизу вверх" мы думали только о том, что вернуть родителю. В паттерне "сверху вниз" добавляется второй вопрос — что передать от родителя ребёнку. То есть теперь нужно думать в обе стороны: что спускаем вниз и что возвращаем наверх.

Суть паттерна "сверху вниз" — при спуске от корня к листьям каждый узел передаёт ребёнку накопленную информацию (например: сумму, глубину, границы, максимум). Благодаря этому в любом узле мы знаем всё, что было выше.

def solve(node, ...):
    if node is None:
        return ...                # базовый случай

    # обновляем переданное значение
    ...

    # рекурсивный спуск с передачей информации детям
    return solve(node.left, ...) or solve(node.right, ...)
Разбор задачи

Дан корень бинарного дерева. Нужно вернуть значения узлов по уровням — сначала все узлы на глубине 0, потом на глубине 1, и так далее.

Ключевая идея решения такая: cпускаемся от корня и несём вниз номер текущего уровня. В каждом узле добавляем его значение в список соответствующего уровня. Если списка для текущего уровня ещё нет — создаём его.

using System.Collections.Generic;

public class Solution
{
    public static List<List<int>> LevelOrderTraversal(TreeNode root)
    {
        List<List<int>> result = new List<List<int>>();
        Preorder(root, 0, result);
        return result;
    }

    private static void Preorder(TreeNode node, int level, List<List<int>> levels)
    {
        if (node == null)
        {
            return;
        }

        // Создаём список для нового уровня
        if (level == levels.Count)
        {
            levels.Add(new List<int>());
        }
        levels[level].Add(node.val);

        Preorder(node.left, level + 1, levels);
        Preorder(node.right, level + 1, levels);
    }
}

Оценка сложности

  • Время: O(n), где n — число вершин в дереве, в худшем случае обходим все узлы
  • Память: O(h), где h — высота дерева, память тратится на стек рекурсивных вызовов

Маркеры паттерна "сверху вниз": нужно передавать дополнительную информацию от корня к листьям — сумму, глубину, границы, максимум для формирования ответа.