главная новое лучшее написать
3

На нашей новой задаче 2415. Reverse Odd Levels of Binary Tree есть повод продемонстировать продвинутые методы Rust работы с итераторами (std::iter::successors & std::iter::zip), а также "непристойную" работу c реф-каунт ячейками :(

📜 Описание задачи

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

💡 Идея

Мы адаптируем BFS для обхода дерева по уровням. На каждом уровне проверяется, нужно ли инвертировать порядок значений (для нечетных уровней). С помощью вспомогательной функции формируются следующие уровни дерева.

📋 Подробности подхода

  1. Вспомогательная функция next_level:
    • Формирует следующий уровень дерева, собирая всех левых и правых потомков текущих узлов.
  2. Завершение обработки:
    • Проверка, что текущий уровень является листовым, выполняется через условие nodes[0].borrow().left.is_none().
    • При достижении уровня листьев обработка завершается.
  3. Обход уровней с помощью std::iter::successors:
    • Используется функциональный подход для последовательного формирования уровней дерева. Итератор автоматически останавливается при достижении листового уровня.
  4. Инверсия значений:
    • На нечетных уровнях значения узлов меняются местами с помощью двух индексов (left и right), начиная с концов уровня и двигаясь к центру.

📊 Асимптотики

💻 Исходный код

    // Definition for a binary tree node.
    // #[derive(Debug, PartialEq, Eq)]
    // pub struct TreeNode {
    //   pub val: i32,
    //   pub left: Option<Rc<RefCell<TreeNode>>>,
    //   pub right: Option<Rc<RefCell<TreeNode>>>,
    // }

    use std::rc::Rc;
    use std::cell::RefCell;
    use std::iter::{successors, zip};

    type LevelNodes = Vec<Rc<RefCell<TreeNode>>>;

    impl Solution {

        // Generate the next level of nodes and increment the level index
        fn next_level((nodes, level): &(LevelNodes, usize)) -> Option<(LevelNodes, usize)> {
            // If the first node has no left child, we have reached the leaf level
            if nodes[0].borrow().left.is_none() {
                return None;
            }

            // Collect all left and right children of the current level nodes
            let next_nodes: LevelNodes = nodes.iter()
                .flat_map(|node| {
                    let node = node.borrow();
                    vec![node.left.clone().unwrap(), node.right.clone().unwrap()]
                }).collect();

            Some((next_nodes, level + 1))
        }

        pub fn reverse_odd_levels(root: Option<Rc<RefCell<TreeNode>>>) -> Option<Rc<RefCell<TreeNode>>> {
            // Early return if the tree is empty
            if root.is_none() {
                return root;
            }

            // Create an iterator for all levels of the tree
            let levels_iter = successors(
                Some((vec![root.clone().unwrap()], 0)),
                Self::next_level
            );

            // Iterate over levels and reverse node values at odd levels
            for (level_nodes, level_index) in levels_iter {
                if level_index % 2 == 1 {
                    let indices = 0..level_nodes.len();
                    for (left, right) in zip(indices.clone(), indices.rev()) {
                        if left < right {
                            // Swap values of nodes from both ends of the level
                            let val_left = level_nodes[left].borrow().val;
                            let val_right = level_nodes[right].borrow().val;

                            level_nodes[left].borrow_mut().val = val_right;
                            level_nodes[right].borrow_mut().val = val_left;
                        } else {
                            break
                        }
                    }
                }
            }

            root
        }
    }