Skip to content
intermediatePhase 4 · Trees & Heaps

Binary Trees

Understand tree traversal, construction, and recursive problem solving.

1h 30m
8 problems
Topic Progress0%

Binary Tree Fundamentals

A binary tree is a hierarchical data structure where each node has at most two children, referred to as left and right.

Node Structure

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

Key Terminology

Term Definition
Root Topmost node (no parent)
Leaf Node with no children
Height Longest path from node to leaf
Depth Distance from root to node
Degree Number of children (0, 1, or 2)

Tree Types

  • Full Binary Tree: Every node has 0 or 2 children
  • Complete Binary Tree: All levels filled except possibly last, filled left to right
  • Balanced Binary Tree: Height difference between left and right subtrees ≤ 1

Visual Example

        1          ← Root (depth=0, height=3)
       / \
      2   3        ← depth=1
     / \\   \
    4   5   6      ← depth=2
   / \\      \
  7   8      9     ← Leaves (depth=3)

Building a Binary Tree

// Manual construction
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);

Computing Height Recursively

public int height(TreeNode root) {
    if (root == null) return -1;  // or 0 for node count
    return 1 + Math.max(height(root.left), height(root.right));
}

Counting Nodes

public int countNodes(TreeNode root) {
    if (root == null) return 0;
    return 1 + countNodes(root.left) + countNodes(root.right);
}

Key Insight: Recursive Thinking

Every binary tree problem follows the same pattern:

  1. Base case: null node → return default value
  2. Recursive case: solve for left subtree, solve for right subtree
  3. Combine: use current node's value with left/right results

This "trust the recursion" approach is the foundation of all tree problems.

DFS vs BFS in Trees

Depth-First Search (DFS)

Explores as deep as possible before backtracking. Three variants:

// 1. Pre-order: Root → Left → Right
public void preorder(TreeNode root) {
    if (root == null) return;
    System.out.print(root.val + " ");  // Visit root first
    preorder(root.left);
    preorder(root.right);
}

// 2. In-order: Left → Root → Right
public void inorder(TreeNode root) {
    if (root == null) return;
    inorder(root.left);
    System.out.print(root.val + " ");  // Visit root between
    inorder(root.right);
}

// 3. Post-order: Left → Right → Root
public void postorder(TreeNode root) {
    if (root == null) return;
    postorder(root.left);
    postorder(root.right);
    System.out.print(root.val + " ");  // Visit root last
}

Breadth-First Search (BFS)

Explores level by level using a queue:

public void levelOrder(TreeNode root) {
    if (root == null) return;
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);

    while (!queue.isEmpty()) {
        int size = queue.size();
        for (int i = 0; i < size; i++) {
            TreeNode node = queue.poll();
            System.out.print(node.val + " ");
            if (node.left != null) queue.offer(node.left);
            if (node.right != null) queue.offer(node.right);
        }
        System.out.println();  // New level
    }
}

Comparison

Aspect DFS BFS
Data Structure Stack (or recursion) Queue
Space Complexity O(h) height O(w) max width
Use Case Path finding, tree height Level-order, shortest path
Iterative? Yes (with explicit stack) Yes (with queue)

When to Use What

  • DFS: Problems involving paths, subtrees, or exploring all possibilities
  • BFS: Problems involving level-by-level processing, minimum depth, or shortest path

Practice Problems

0/4solved
Maximum Depth of Binary Tree
Recursive DFS

Given the root of a binary tree, return its maximum depth. Maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

Example:

Input: root = [3,9,20,null,null,15,7]

Output: 3

Path 3→20→7 or 3→20→15 has 3 nodes.

Optimal Solution — O(n) time, O(h) where h is tree height, O(log n) for balanced, O(n) worst case space

Recursive DFS - max depth = 1 + max(left depth, right depth)

class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) return 0;
        return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
    }
}

Edge Cases:

  • Empty tree (root is null) → return 0
  • Single node → return 1
  • Skewed tree (all left or all right) → return n
Construct Binary Tree from Preorder and Inorder Traversal
Recursive Construction

Given two integer arrays preorder and inorder, construct and return the binary tree.

Example:

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

Output: [3,9,20,null,null,15,7]

Preorder gives root first. Inorder splits into left and right subtrees.

Optimal Solution — O(n) time, O(n) for recursion and map space

Recursive: first element of preorder is root, find root in inorder to split

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return build(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
    }
    
    private TreeNode build(int[] preorder, int preStart, int preEnd,
                           int[] inorder, int inStart, int inEnd) {
        if (preStart > preEnd || inStart > inEnd) return null;
        
        int rootVal = preorder[preStart];
        TreeNode root = new TreeNode(rootVal);
        
        int rootIndex = inStart;
        while (inorder[rootIndex] != rootVal) rootIndex++;
        
        int leftSize = rootIndex - inStart;
        root.left = build(preorder, preStart + 1, preStart + leftSize, inorder, inStart, rootIndex - 1);
        root.right = build(preorder, preStart + leftSize + 1, preEnd, inorder, rootIndex + 1, inEnd);
        
        return root;
    }
}

Edge Cases:

  • Single node
  • Only left children
  • Only right children
Binary Tree Right Side View
BFS / DFS

Given the root of a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.

Example:

Input: root = [1,2,3,null,5,null,4]

Output: [1,3,4]

From the right side, you see nodes 1, 3, and 4.

Optimal Solution — O(n) time, O(n) space

BFS: last node at each level is the right side view

class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) return result;
        
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if (i == size - 1) result.add(node.val);
                if (node.left != null) queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
            }
        }
        return result;
    }
}

Edge Cases:

  • Empty tree
  • Single node
  • Left-skewed tree
Flatten Binary Tree to Linked List
Reverse Preorder

Given the root of a binary tree, flatten the tree into a linked list in-place using preorder traversal.

Example:

Input: root = [1,2,5,3,4,null,6]

Output: [1,null,2,null,3,null,4,null,5,null,6]

Right child points to next node in preorder.

Optimal Solution — O(n) time, O(h) recursion depth space

Reverse preorder: process right, then left, maintain previous pointer

class Solution {
    private TreeNode prev = null;
    
    public void flatten(TreeNode root) {
        if (root == null) return;
        flatten(root.right);
        flatten(root.left);
        root.right = prev;
        root.left = null;
        prev = root;
    }
}

Edge Cases:

  • Empty tree
  • Single node
  • Already flat tree

Quiz

1. What is the maximum number of nodes in a binary tree of height h?

Question 1 options

2. Which traversal visits nodes in Left → Root → Right order?

Question 2 options

3. What is the primary purpose of Binary Trees?

Question 3 options

4. What is a common mistake when implementing Binary Trees?

Question 4 options

Flashcards

Question

What are the three DFS traversal orders for binary trees?

Answer

Pre-order (Root→Left→Right), In-order (Left→Root→Right), Post-order (Left→Right→Root). Each visits root at a different point relative to children.

Question

What is the recursive pattern for binary tree problems?

Answer

1) Base case: null node returns default. 2) Recursive case: solve left and right subtrees. 3) Combine: use current node's value with left/right results.

Question

What is Binary Trees?

Answer

Binary Trees is a key concept in software engineering.

Question

When to use Binary Trees?

Answer

Use Binary Trees when building production systems that require reliability, scalability, and maintainability.

Question

Binary Trees best practices

Answer

Follow SOLID principles, write clean code, test thoroughly, document decisions, and monitor in production.

Revision Notes

Key Takeaways

  • 1.Every binary tree problem follows the recursive template: base case + recurse + combine
  • 2.DFS uses stack (or recursion), BFS uses queue
  • 3.In-order traversal of BST yields sorted order
  • 4.Tree height determines DFS space complexity

Interview Tips

  • Start with recursive solution, then optimize to iterative if needed
  • Always handle null root as base case
  • Clarify if tree is balanced - affects complexity
  • Mention both time O(n) and space O(h) complexities

Cheat Sheet

Binary Trees Cheat Sheet

Node Definition:

class TreeNode {
    int val;
    TreeNode left, right;
}

Core Recursion Template:

public ReturnType solve(TreeNode root) {
    if (root == null) return baseValue;
    ReturnType left = solve(root.left);
    ReturnType right = solve(root.right);
    return combine(root.val, left, right);
}

DFS Traversals:

  • Pre-order: Root → Left → Right (copy tree, serialize)
  • In-order: Left → Root → Right (sorted order in BST)
  • Post-order: Left → Right → Root (delete tree, compute height)

BFS Template:

Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
    int size = queue.size();
    for (int i = 0; i < size; i++) {
        TreeNode node = queue.poll();
        // process node
        if (node.left != null) queue.offer(node.left);
        if (node.right != null) queue.offer(node.right);
    }
}

Key Formulas:

  • Max nodes at level i: 2^i
  • Max nodes in tree height h: 2^(h+1) - 1
  • Height = ⌊log₂(n)⌋ for balanced tree