Lesson 88 of 250
226. Invert Binary Tree
NeetCode: Invert Binary Tree · LeetCode: 226. Invert Binary Tree · Difficulty: Easy
Given the root of a binary tree, invert it (swap the left and right child of every node) and return the root.
Example
Input: 1 Output: 1
/ \ / \
2 3 3 2
/ \ / \
4 5 5 4Trees are given in LeetCode's level-order array form: the root first, then each level from left to right, with null marking a missing node, so [1, 2, 3, 4, 5] is the tree above. The tree(Integer... values) helper in each program builds a TreeNode from such an array by filling children from a queue. TreeNode has the fields val, left, and right. A missing child is null: Java object references are nullable and the fields are mutable, so no wrapper type is needed.
Brute force: build a mirrored copy
Recursively create a new node for every original node, giving it the mirror image of the other subtree.
import java.util.ArrayDeque;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
TreeNode copy = new TreeNode(root.val);
copy.left = invertTree(root.right);
copy.right = invertTree(root.left);
return copy;
}
}
public class Main {
/** Builds a tree from LeetCode's level-order array, where null marks a missing node. */
static TreeNode tree(Integer... values) {
if (values.length == 0 || values[0] == null) return null;
TreeNode root = new TreeNode(values[0]);
ArrayDeque<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
int i = 1;
while (!queue.isEmpty() && i < values.length) {
TreeNode node = queue.poll();
if (i < values.length && values[i] != null) {
node.left = new TreeNode(values[i]);
queue.add(node.left);
}
i++;
if (i < values.length && values[i] != null) {
node.right = new TreeNode(values[i]);
queue.add(node.right);
}
i++;
}
return root;
}
/** Preorder listing with N for a missing child. */
static String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
serializeInto(root, sb);
return sb.toString();
}
static void serializeInto(TreeNode node, StringBuilder sb) {
if (sb.length() > 0) sb.append(',');
if (node == null) {
sb.append('N');
return;
}
sb.append(node.val);
serializeInto(node.left, sb);
serializeInto(node.right, sb);
}
public static void main(String[] args) {
TreeNode root = tree(1, 2, 3, 4, 5);
System.out.println(serialize(new Solution().invertTree(root)));
System.out.println(serialize(new Solution().invertTree(null)));
}
}1,3,N,N,2,5,N,N,4,N,N
NThe output is a preorder listing, with N for a missing child. The original tree is left unchanged. Time: O(n). Space: O(n) for the copy, plus O(h) recursion.
Optimal: swap the children in place
Invert both subtrees, then attach them swapped. No new nodes are allocated; the same TreeNode objects are reused and the original tree is modified. The code saves the old left child in a local variable before overwriting root.left.
import java.util.ArrayDeque;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
TreeNode left = root.left;
root.left = invertTree(root.right);
root.right = invertTree(left);
return root;
}
}
public class Main {
/** Builds a tree from LeetCode's level-order array, where null marks a missing node. */
static TreeNode tree(Integer... values) {
if (values.length == 0 || values[0] == null) return null;
TreeNode root = new TreeNode(values[0]);
ArrayDeque<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
int i = 1;
while (!queue.isEmpty() && i < values.length) {
TreeNode node = queue.poll();
if (i < values.length && values[i] != null) {
node.left = new TreeNode(values[i]);
queue.add(node.left);
}
i++;
if (i < values.length && values[i] != null) {
node.right = new TreeNode(values[i]);
queue.add(node.right);
}
i++;
}
return root;
}
/** Preorder listing with N for a missing child. */
static String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
serializeInto(root, sb);
return sb.toString();
}
static void serializeInto(TreeNode node, StringBuilder sb) {
if (sb.length() > 0) sb.append(',');
if (node == null) {
sb.append('N');
return;
}
sb.append(node.val);
serializeInto(node.left, sb);
serializeInto(node.right, sb);
}
public static void main(String[] args) {
TreeNode root = tree(1, 2, 3, 4, 5);
System.out.println(serialize(new Solution().invertTree(root)));
System.out.println(serialize(new Solution().invertTree(null)));
}
}1,3,N,N,2,5,N,N,4,N,N
NTime: O(n). Space: O(h) for the recursion, where h is the height (O(log n) balanced, O(n) for a chain). A very deep chain can overflow the thread stack, which an explicit ArrayDeque stack avoids.
