Prompt

Invert a binary tree in Rust

4 AI models answered this prompt

Try Chappie free →

Responses

Here's how to invert a binary tree in Rust:

use std::cell::RefCell;
use std::rc::Rc;

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

impl TreeNode {
    fn new(val: i32) -> Self {
        TreeNode {
            val,
            left: None,
            right: None,
        }
    }
}

type Node = Option<Rc<RefCell<TreeNode>>>;

/// Recursively inverts a binary tree by swapping left and right children.
fn invert_tree(root: Node) -> Node {
    if let Some(node) = root.as_ref() {
        let mut node_ref = node.borrow_mut();

        // Swap left and right subtrees
        let left = node_ref.left.take();
        let right = node_ref.right.take();
        node_ref.left = invert_tree(right);
        node_ref.right = invert_tree(left);
    }
    root
}

// ---------- helpers for testing ----------

fn new_node(val: i32, left: Node, right: Node) -> Node {
    Some(Rc::new(RefCell::new(TreeNode {
        val,
        left,
        right,
    })))
}

/// Returns an in-order traversal as a Vec for easy comparison.
fn inorder(root: &Node) -> Vec<i32> {
    let mut result = Vec::new();
    if let Some(node) = root {
        let node_ref = node.borrow();
        result.extend(inorder(&node_ref.left));
        result.push(node_ref.val);
        result.extend(inorder(&node_ref.right));
    }
    result
}

fn main() {
    //        4
    //       / \
    //      2   7
    //     / \ / \
    //    1  3 6  9
    let tree = new_node(
        4,
        new_node(2, new_node(1, None, None), new_node(3, None, None)),
        new_node(7, new_node(6, None, None), new_node(9, None, None)),
    );

    println!("Before: {:?}", inorder(&tree));  // [1, 2, 3, 4, 6, 7, 9]

    let inverted = invert_tree(tree);

    println!("After:  {:?}", inorder(&inverted)); // [9, 7, 6, 4, 3, 2, 1]
    //        4
    //       / \
    //      7   2
    //     / \ / \
    //    9  6 3  1
}

How it works

StepWhat happens
Base caseIf the node is None, return None — nothing to invert.
Recursive step.take() both children (moves them out), then recursively invert each and assign them to the opposite side.
OwnershipRc<RefCell<T>> is the standard Rust pattern for shared, mutable tree nodes. borrow_mut() gives interior mutability.

Complexity

  • Time: O(n) — every node is visited exactly once.
  • Space: O(h) — call stack depth equals tree height (O(log n) balanced, O(n) worst-case skewed).

Iterative alternative (BFS)

If you prefer to avoid recursion:

use std::collections::VecDeque;

fn invert_tree_iterative(root: Node) -> Node {
    let mut queue = VecDeque::new();
    if let Some(ref node) = root {
        queue.push_back(Rc::clone(node));
    }

    while let Some(node) = queue.pop_front() {
        let mut n = node.borrow_mut();

        // Swap children
        std::mem::swap(&mut n.left, &mut n.right);

        // Enqueue children for processing
        if let Some(ref left) = n.left {
            queue.push_back(Rc::clone(left));
        }
        if let Some(ref right) = n.right {
            queue.push_back(Rc::clone(right));
        }
    }

    root
}

This uses a VecDeque as a queue for level-order traversal, swapping children at each node without recursion.

anthropic
Answered by Claude Opus 4.6

Claude Opus 4.6

Here's how to invert a binary tree in Rust: use std::cell::RefCell; use std::rc::Rc; // Definition of a binary tree node #[derive(Debug)] struct TreeNode { val: i32, left: Option<Rc<RefCell<TreeNode>>>, right: Option<Rc<RefCell<TreeNode>>>, } impl TreeNode { fn new(val: i32) -> Self { TreeNode { val, left: None, right: None, } } } type Node = Option<Rc<RefCell<TreeNode>>>; /// Recursively inverts a binary tree by swapping left and right children. fn invert_tree(root: Node) -> Node { if let Some(node) = root.as_ref() { let mut node_ref = node.borrow_mut(); // Swap left and right subtrees let left = node_ref.left.take(); let right = node_ref.right.take(); node_ref.left = invert_tree(right); node_ref.right = invert_tree(left); } root } // ---------- helpers for testing ---------- fn new_node(val: i32, left: Node, right: Node) -> Node { Some(Rc::new(RefCell::new(TreeNode { val, left, right, }))) } /// Returns an in-order traversal as a Vec for easy comparison. fn inorder(root: &Node) -> Vec<i32> { let mut result = Vec::new(); if let Some(node) = root { let node_ref = node.borrow(); result.extend(inorder(&node_ref.left)); result.push(node_ref.val); result.extend(inorder(&node_ref.right)); } result } fn main() { // 4 // / \ // 2 7 // / \ / \ // 1 3 6 9 let tree = new_node( 4, new_node(2, new_node(1, None, None), new_node(3, None, None)), new_node(7, new_node(6, None, None), new_node(9, None, None)), ); println!("Before: {:?}", inorder(&tree)); // [1, 2, 3, 4, 6, 7, 9] let inverted = invert_tree(tree); println!("After: {:?}", inorder(&inverted)); // [9, 7, 6, 4, 3, 2, 1] // 4 // / \ // 7 2 // / \ / \ // 9 6 3 1 } How it works | Step | What happens | |---|---| | Base case | If the node is None, return None — nothing to invert. | | Recursive step | .take() both children (moves them out), then recursively invert each and assign them to the opposite side. | | Ownership | Rc<RefCell<T>> is the standard Rust pattern for shared, mutable tree nodes. borrow_mut() gives interior mutability. | Complexity Time: O(n) — every node is visited exactly once. Space: O(h) — call stack depth equals tree height (O(log n) balanced, O(n) worst-case skewed). Iterative alternative (BFS) If you prefer to avoid recursion: use std::collections::VecDeque; fn invert_tree_iterative(root: Node) -> Node { let mut queue = VecDeque::new(); if let Some(ref node) = root { queue.push_back(Rc::clone(node)); } while let Some(node) = queue.pop_front() { let mut n = node.borrow_mut(); // Swap children std::mem::swap(&mut n.left, &mut n.right); // Enqueue children for processing if let Some(ref left) = n.left { queue.push_back(Rc::clone(left)); } if let Some(ref right) = n.right { queue.push_back(Rc::clone(right)); } } root } This uses a VecDeque as a queue for level-order traversal, swapping children at each node without recursion.

Sonnet 4.6

Here's a complete, well-commented implementation of inverting a binary tree in Rust — covering both a simple Box-based tree and the Rc<RefCell<>> version used in LeetCode. Approach We recursively call a swap function on all left & right nodes until we reach the leaves. If the input node is None, return None. Otherwise, we recursively invert both child nodes, then install the inverted left as right, and the inverted right as left. Version 1: Simple Box-based Tree (Owned) This is the cleanest Rust-idiomatic approach when you own the tree: #[derive(Debug)] struct TreeNode { val: i32, left: Option<Box<TreeNode>>, right: Option<Box<TreeNode>>, } impl TreeNode { fn new(val: i32) -> Self { TreeNode { val, left: None, right: None } } fn with_children(val: i32, left: Option<Box<TreeNode>>, right: Option<Box<TreeNode>>) -> Self { TreeNode { val, left, right } } } /// Recursively inverts a binary tree by swapping left and right children. fn invert_tree(root: Option<Box<TreeNode>>) -> Option<Box<TreeNode>> { root.map(|mut node| { // Recursively invert children, then swap them let left = invert_tree(node.left.take()); let right = invert_tree(node.right.take()); node.left = right; node.right = left; node }) } fn main() { // Build this tree: // 4 // / \ // 2 7 // / \ / \ // 1 3 6 9 let tree = Some(Box::new(TreeNode::with_children( 4, Some(Box::new(TreeNode::with_children( 2, Some(Box::new(TreeNode::new(1))), Some(Box::new(TreeNode::new(3))), ))), Some(Box::new(TreeNode::with_children( 7, Some(Box::new(TreeNode::new(6))), Some(Box::new(TreeNode::new(9))), ))), ))); let inverted = invert_tree(tree); // Expected: // 4 // / \ // 7 2 // / \ / \ // 9 6 3 1 println!("{:#?}", inverted); } Version 2: Rc<RefCell<>> Tree (LeetCode style) The LeetCode TreeNode wraps children in Option<Rc<RefCell<TreeNode>>>. RefCell is a mutable, shareable container, and Rc is a reference-counting container that tracks how many references exist. use std::rc::Rc; use std::cell::RefCell; #[derive(Debug, PartialEq, Eq)] pub struct TreeNode { pub val: i32, pub left: Option<Rc<RefCell<TreeNode>>>, pub right: Option<Rc<RefCell<TreeNode>>>, } impl TreeNode { pub fn new(val: i32) -> Self { TreeNode { val, left: None, right: None } } } pub fn invert_tree( root: Option<Rc<RefCell<TreeNode>>> ) -> Option<Rc<RefCell<TreeNode>>> { if let Some(node) = root.clone() { let mut node_ref = node.borrow_mut(); // Take ownership of children, recursively invert, then swap let left = invert_tree(node_ref.left.take()); let right = invert_tree(node_ref.right.take()); node_ref.left = right; node_ref.right = left; } root // Return same root — it's been mutated in-place } We have modified node_ref, which is still a reference to the same data as root holds — so returning root returns the modified tree. Complexity | | Complexity | |---|---| | Time | O(n), where n is the number of input nodes | | Space | O(d), where d is the depth of the longest branch (call stack) | Key Rust Concepts at Play | Concept | Role | |---|---| | Option<Box<T>> | Owned nullable child pointer | | .take() | Moves value out of Option, leaving None | | .map() | Transforms Some(T) without unwrapping unsafely | | Rc<RefCell<T>> | Shared ownership + interior mutability for LeetCode trees | | borrow_mut() | Runtime-checked mutable borrow via RefCell | The Box-based version is preferred for general use — it's simpler and more idiomatic. Use Rc<RefCell<>> only when shared ownership is required (e.g., LeetCode constraints).

Claude Sonnet 4.5

Here's how to invert a binary tree in Rust: use std::rc::Rc; use std::cell::RefCell; // 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>>>, } impl TreeNode { #[inline] pub fn new(val: i32) -> Self { TreeNode { val, left: None, right: None, } } } // Solution: Invert the binary tree pub fn invert_tree(root: Option<Rc<RefCell<TreeNode>>>) -> Option<Rc<RefCell<TreeNode>>> { if let Some(node) = root { let mut node_ref = node.borrow_mut(); // Swap left and right children let left = node_ref.left.take(); let right = node_ref.right.take(); node_ref.left = invert_tree(right); node_ref.right = invert_tree(left); drop(node_ref); // Release the borrow Some(node.clone()) } else { None } } // Example usage fn main() { // Create a tree: // 4 // / \ // 2 7 // / \ / \ // 1 3 6 9 let root = Rc::new(RefCell::new(TreeNode { val: 4, left: Some(Rc::new(RefCell::new(TreeNode { val: 2, left: Some(Rc::new(RefCell::new(TreeNode::new(1)))), right: Some(Rc::new(RefCell::new(TreeNode::new(3)))), }))), right: Some(Rc::new(RefCell::new(TreeNode { val: 7, left: Some(Rc::new(RefCell::new(TreeNode::new(6)))), right: Some(Rc::new(RefCell::new(TreeNode::new(9)))), }))), })); let inverted = invert_tree(Some(root)); // After inversion: // 4 // / \ // 7 2 // / \ / \ // 9 6 3 1 } Alternative: Iterative approach using a stack use std::collections::VecDeque; pub fn invert_tree_iterative(root: Option<Rc<RefCell<TreeNode>>>) -> Option<Rc<RefCell<TreeNode>>> { if root.is_none() { return None; } let mut queue = VecDeque::new(); queue.push_back(root.clone()); while let Some(Some(node)) = queue.pop_front() { let mut node_ref = node.borrow_mut(); // Swap children std::mem::swap(&mut node_ref.left, &mut node_ref.right); // Add children to queue if node_ref.left.is_some() { queue.push_back(node_ref.left.clone()); } if node_ref.right.is_some() { queue.push_back(node_ref.right.clone()); } } root } Simpler version with Box (if you control the tree definition) #[derive(Debug)] pub struct TreeNode { pub val: i32, pub left: Option<Box<TreeNode>>, pub right: Option<Box<TreeNode>>, } pub fn invert_tree(root: Option<Box<TreeNode>>) -> Option<Box<TreeNode>> { root.map(|mut node| { // Swap and recursively invert let left = invert_tree(node.left); let right = invert_tree(node.right); node.left = right; node.right = left; node }) } Key points: Recursive approach: Swap left and right children at each node, then recursively invert subtrees Rc<RefCell<>>: Used for shared ownership (common in LeetCode-style problems) Box: Simpler if you control the data structure—allows moving ownership Time complexity: O(n) - visit each node once Space complexity: O(h) - recursion stack depth (h = tree height) Choose the Box version if possible—it's more idiomatic Rust. Use Rc<RefCell<>> when you need shared references or are working with existing interfaces.

Claude Opus 4.5

Here's how to invert a binary tree in Rust: // Definition for a binary tree node #[derive(Debug, Clone)] struct TreeNode { val: i32, left: Option<Box<TreeNode>>, right: Option<Box<TreeNode>>, } impl TreeNode { fn new(val: i32) -> Self { TreeNode { val, left: None, right: None, } } } // Recursive solution fn invert_tree(root: Option<Box<TreeNode>>) -> Option<Box<TreeNode>> { match root { None => None, Some(mut node) => { // Swap left and right children let temp = node.left.take(); node.left = invert_tree(node.right.take()); node.right = invert_tree(temp); Some(node) } } } // Iterative solution using a stack fn invert_tree_iterative(root: Option<Box<TreeNode>>) -> Option<Box<TreeNode>> { let mut root = root; if root.is_none() { return None; } let mut stack = vec![root.as_mut().unwrap().as_mut()]; while let Some(node) = stack.pop() { // Swap children std::mem::swap(&mut node.left, &mut node.right); // Push children onto stack if let Some(ref mut left) = node.left { stack.push(left.as_mut()); } if let Some(ref mut right) = node.right { stack.push(right.as_mut()); } } root } fn main() { // Build a sample tree: // 4 // / \ // 2 7 // / \ / \ // 1 3 6 9 let mut root = Box::new(TreeNode::new(4)); root.left = Some(Box::new(TreeNode::new(2))); root.right = Some(Box::new(TreeNode::new(7))); if let Some(ref mut left) = root.left { left.left = Some(Box::new(TreeNode::new(1))); left.right = Some(Box::new(TreeNode::new(3))); } if let Some(ref mut right) = root.right { right.left = Some(Box::new(TreeNode::new(6))); right.right = Some(Box::new(TreeNode::new(9))); } println!("Original: {:?}", root); let inverted = invert_tree(Some(root)); // Result: // 4 // / \ // 7 2 // / \ / \ // 9 6 3 1 println!("Inverted: {:?}", inverted); } Key Points | Aspect | Details | |--------|---------| | Time Complexity | O(n) - visit each node once | | Space Complexity | O(h) - where h is tree height (recursion stack) | | Ownership | Uses Option<Box<TreeNode>> for heap allocation | | take() | Moves value out of Option, leaving None | The Two Approaches 1. Recursive (simpler) Base case: return None for empty nodes Recursively invert children, then swap them 2. Iterative (avoids stack overflow on deep trees) Use explicit stack/queue Process each node: swap its children, push children to stack Both solutions handle Rust's ownership model by using: Option for nullable children Box for heap-allocated nodes .take() to move values without borrowing issues

Chappie

Try Chappie free

Compare 4 AI models side by side.

Download on the App StoreShared from Chappie
Chappie

Try Chappie free

Compare 4 AI models side by side.

Download