Prompt
Invert a binary tree in Rust
4 AI models answered this prompt
Try ChatXOS 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
| 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.
Opus 4.6
Here's how to invert a binary tree in Rust: 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: 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: --- 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. 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).
Sonnet 4.5
Here's how to invert a binary tree in Rust: Alternative: Iterative approach using a stack Simpler version with Box (if you control the tree definition) 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.
Opus 4.5
Here's how to invert a binary tree in Rust: 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