Maximum Level in Binary Tree

Last Updated : 2 Oct, 2026

Given a binary tree, find its maximum level (the deepest level that contains at least one node). Root is considered at level 1.

Examples:

Input: root = [1, 3, 2, 4, N, N, N]

1

Output: 3
Explanation: The farthest leaf node is 4, which is located at level 3.

Input: root = [10, 20, 30, N, 40, N, 60, N, N, 2, N, N, N]

2

Output: 4
Explanation: The farthest leaf node is 2, which is located at level 4.

Recursion - O(n) Time and O(h) Space

The idea is to recursively find the maximum level of the left and right subtrees for each node.

The maximum level of the current node is calculated as 1 + max(leftLevel, rightLevel), where 1 represents the current node.

The recursion stops when we reach a null node, which returns 0. For a leaf node, the maximum level is 1.

Consider the following tree to understand the flow:

2

maxLevel('10') = max(maxLevel('20'), maxLevel('30')) + 1 = max(2, 3) + 1 = 4.

This is because recursively:

  • maxLevel('20') = max(maxLevel(NULL), maxLevel('40')) + 1 = max(0, 1) + 1 = 2
  • maxLevel('30') = max(maxLevel(NULL), maxLevel('60')) + 1 = max(0, 2) + 1 = 3
  • maxLevel('40') = max(maxLevel(NULL), maxLevel(NULL)) + 1 = max(0, 0) + 1 = 1
  • maxLevel('60') = max(maxLevel('2'), maxLevel(NULL)) + 1 = max(1, 0) + 1 = 2
  • maxLevel('2') = max(maxLevel(NULL), maxLevel(NULL)) + 1 = max(0, 0) + 1 = 1
C++
#include <iostream>
#include <climits>
#include <algorithm>
using namespace std;

class Node
{
  public:
    int data;
    Node *left;
    Node *right;

    Node(int val)
    {
        data = val;
        left = right = nullptr;
    }
};

int maxLevel(Node *root)
{
    if (root == nullptr)
        return 0;

    if (root->left == nullptr and root->right == nullptr)
        return 1;
    // no child nodes indicate base case

    int left, right;

    if (root->left != nullptr)
        left = maxLevel(root->left);

    // finding depth of left sub tree
    else
        left = INT_MIN;

    if (root->right != nullptr)
        right = maxLevel(root->right);

    // finding depth of right sub tree
    else
        right = INT_MIN;

    return 1 + max(left, right);
}

int main()
{
    // Representation of the input tree:
    //        10
    //       /  \
    //     20    30
    //       \    \
    //       40    60
    //            /
    //           2

    Node *root = new Node(10);
    root->left = new Node(20);
    root->right = new Node(30);
    root->left->right = new Node(40);
    root->right->right = new Node(60);
    root->right->right->left = new Node(2);

    cout << maxLevel(root);

    return 0;
}
C
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct Node
{
    int data;
    struct Node *left;
    struct Node *right;
} Node;

Node *createNode(int val)
{
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = val;
    newNode->left = newNode->right = NULL;
    return newNode;
}

int maxLevel(Node *root)
{
    if (root == NULL)
        return 0;

    if (root->left == NULL && root->right == NULL)
        return 1;
    // no child nodes indicate base case

    int left = INT_MIN, right = INT_MIN;

    if (root->left != NULL)
        left = maxLevel(root->left);

    // finding depth of left sub tree

    if (root->right != NULL)
        right = maxLevel(root->right);

    // finding depth of right sub tree

    return 1 + (left > right ? left : right);
}

int main()
{
    // Representation of the input tree:
    //        10
    //       /  \
    //     20    30
    //       \    \
    //       40    60
    //             /
    //            2

    Node *root = createNode(10);
    root->left = createNode(20);
    root->right = createNode(30);
    root->left->right = createNode(40);
    root->right->right = createNode(60);
    root->right->right->left = createNode(2);

    printf("%d", maxLevel(root));
    return 0;
}
Java
import java.util.Arrays;

class Node {
    int data;
    Node left;
    Node right;

    Node(int val)
    {
        data = val;
        left = right = null;
    }
}

public class GFG {
    static int maxLevel(Node root)
    {
        if (root == null)
            return 0;

        if (root.left == null && root.right == null)
            return 1;
        // no child nodes indicate base case

        int left = Integer.MIN_VALUE, right
                                      = Integer.MIN_VALUE;

        if (root.left != null)
            left = maxLevel(root.left);

        // finding depth of left sub tree

        if (root.right != null)
            right = maxLevel(root.right);

        // finding depth of right sub tree

        return 1 + Math.max(left, right);
    }

    public static void main(String[] args)
    {
        // Representation of the input tree:
        //        10
        //       /  \
        //     20    30
        //       \    \
        //       40    60
        //             /
        //            2

        Node root = new Node(10);
        root.left = new Node(20);
        root.right = new Node(30);
        root.left.right = new Node(40);
        root.right.right = new Node(60);
        root.right.right.left = new Node(2);

        System.out.println(maxLevel(root));
    }
}
Python
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

def maxLevel(root):
    if root is None:
        return 0

    if root.left is None and root.right is None:
        return 1
    # no child nodes indicate base case

    left = float('-inf')
    right = float('-inf')

    if root.left is not None:
        left = maxLevel(root.left)

    # finding depth of left sub tree

    if root.right is not None:
        right = maxLevel(root.right)

    # finding depth of right sub tree

    return 1 + max(left, right)

if __name__ == '__main__':
    # Representation of the input tree:
    #        10
    #       /  \
    #     20    30
    #       \    \
    #       40    60
    #             /
    #            2

    root = Node(10)
    root.left = Node(20)
    root.right = Node(30)
    root.left.right = Node(40)
    root.right.right = Node(60)
    root.right.right.left = Node(2)

    print(maxLevel(root))
C#
using System;

public class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}

public class GFG {
    public static int maxLevel(Node root)
    {
        if (root == null)
            return 0;

        if (root.left == null && root.right == null)
            return 1;
        // no child nodes indicate base case

        int left = int.MinValue, right = int.MinValue;

        if (root.left != null)
            left = maxLevel(root.left);

        // finding depth of left sub tree

        if (root.right != null)
            right = maxLevel(root.right);

        // finding depth of right sub tree

        return 1 + Math.Max(left, right);
    }

    public static void Main()
    {
        // Representation of the input tree:
        //        10
        //       /  \
        //     20    30
        //      \    \
        //       40   60
        //             /
        //            2

        Node root = new Node(10);
        root.left = new Node(20);
        root.right = new Node(30);
        root.left.right = new Node(40);
        root.right.right = new Node(60);
        root.right.right.left = new Node(2);

        Console.WriteLine(maxLevel(root));
    }
}
JavaScript
class Node {
    constructor(val)
    {
        this.data = val;
        this.left = this.right = null;
    }
}

function maxLevel(root)
{
    if (root === null)
        return 0;

    if (root.left === null && root.right === null)
        return 1;
    // no child nodes indicate base case

    let left = Number.NEGATIVE_INFINITY,
        right = Number.NEGATIVE_INFINITY;

    if (root.left !== null)
        left = maxLevel(root.left);

    // finding depth of left sub tree

    if (root.right !== null)
        right = maxLevel(root.right);

    // finding depth of right sub tree

    return 1 + Math.max(left, right);
}

// Driver Code
// Representation of the input tree:
//         10
//        /  \
//      20    30
//       \    \
//        40   60
//              /
//             2

let root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.right = new Node(40);
root.right.right = new Node(60);
root.right.right.left = new Node(2);

console.log(maxLevel(root));

Output
4

Level Order Traversal - O(n) Time and O(n) Space

The idea is to traverse the tree level by level using a queue. At each step, we process all nodes present at the current level and add their children to the queue.

After processing all nodes of a level, we increment the level counter.

When the queue becomes empty, the counter represents the maximum level of the binary tree.

Let us understand with an example:
Input: root = [10, 20, 30, N, 40, N, 60, N, N, 2, N, N, N]

2

The tree is processed level by level:

  • Level 1: 10
  • Level 2: 20, 30
  • Level 3: 40, 60
  • Level 4: 2

After processing all four levels, the queue becomes empty. Therefore, the maximum level is 4.

C++
#include <iostream>
#include <queue>
using namespace std;

class Node
{
  public:
    int data;
    Node *left;
    Node *right;

    Node(int val)
    {
        data = val;
        left = right = nullptr;
    }
};

int maxLevel(Node *root)
{
    if (root == nullptr)
        return 0;

    // Initialize a queue for level order traversal.
    queue<Node *> q;
    q.push(root);

    int level = 0;

    // Traverse the tree level by level.
    while (!q.empty())
    {
        int levelSize = q.size();

        // Process all nodes at the current level.
        for (int i = 0; i < levelSize; i++)
        {
            Node *curr = q.front();
            q.pop();

            // Add the left child to the queue.
            if (curr->left != nullptr)
                q.push(curr->left);

            // Add the right child to the queue.
            if (curr->right != nullptr)
                q.push(curr->right);
        }

        // Move to the next level.
        level++;
    }

    return level;
}

int main()
{
    // Representation of the input tree:
    //        10
    //       /  \
    //     20    30
    //       \    \
    //       40    60
    //            /
    //           2

    Node *root = new Node(10);
    root->left = new Node(20);
    root->right = new Node(30);
    root->left->right = new Node(40);
    root->right->right = new Node(60);
    root->right->right->left = new Node(2);

    cout << maxLevel(root);

    return 0;
}
C
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct Node
{
    int data;
    struct Node *left;
    struct Node *right;
} Node;

Node *newNode(int data)
{
    Node *node = (Node *)malloc(sizeof(Node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return node;
}

typedef struct Queue
{
    Node **items;
    int front, rear, size, capacity;
} Queue;

Queue *createQueue(int capacity)
{
    Queue *queue = (Queue *)malloc(sizeof(Queue));
    queue->items = (Node **)malloc(sizeof(Node *) * capacity);
    queue->front = 0;
    queue->rear = -1;
    queue->size = 0;
    queue->capacity = capacity;
    return queue;
}

bool isEmpty(Queue *queue)
{
    return queue->size == 0;
}

void enqueue(Queue *queue, Node *node)
{
    queue->rear = (queue->rear + 1) % queue->capacity;
    queue->items[queue->rear] = node;
    queue->size++;
}

Node *dequeue(Queue *queue)
{
    Node *node = queue->items[queue->front];
    queue->front = (queue->front + 1) % queue->capacity;
    queue->size--;
    return node;
}

int maxLevel(Node *root)
{
    if (root == NULL)
        return 0;

    Queue *queue = createQueue(100);
    enqueue(queue, root);

    int level = 0;

    while (!isEmpty(queue))
    {
        int levelSize = queue->size;

        for (int i = 0; i < levelSize; i++)
        {
            Node *curr = dequeue(queue);

            if (curr->left != NULL)
                enqueue(queue, curr->left);
            if (curr->right != NULL)
                enqueue(queue, curr->right);
        }

        level++;
    }

    free(queue->items);
    free(queue);

    return level;
}

int main()
{
    // Representation of the input tree:
    //        10
    //       /  \
    //     20    30
    //      \   \
    //       40    60
    //             /
    //           2

    Node *root = newNode(10);
    root->left = newNode(20);
    root->right = newNode(30);
    root->left->right = newNode(40);
    root->right->right = newNode(60);
    root->right->right->left = newNode(2);

    printf("%d", maxLevel(root));

    return 0;
}
Java
import java.util.*;

class Node {
    public int data;
    public Node left, right;

    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}

public class GFG {
    public static int maxLevel(Node root)
    {
        if (root == null)
            return 0;

        Queue<Node> q = new LinkedList<>();
        q.add(root);

        int level = 0;

        while (!q.isEmpty()) {
            int levelSize = q.size();

            for (int i = 0; i < levelSize; i++) {
                Node curr = q.poll();

                if (curr.left != null)
                    q.add(curr.left);
                if (curr.right != null)
                    q.add(curr.right);
            }

            level++;
        }

        return level;
    }

    public static void main(String[] args)
    {
        // Representation of the input tree:
        //        10
        //       /  \
        //     20    30
        //      \   \
        //       40    60
        //             /
        //           2

        Node root = new Node(10);
        root.left = new Node(20);
        root.right = new Node(30);
        root.left.right = new Node(40);
        root.right.right = new Node(60);
        root.right.right.left = new Node(2);

        System.out.println(maxLevel(root));
    }
}
Python
from collections import deque

class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

def maxLevel(root):
    if root is None:
        return 0

    q = deque([root])
    level = 0

    while q:
        levelSize = len(q)

        for _ in range(levelSize):
            curr = q.popleft()

            if curr.left is not None:
                q.append(curr.left)
            if curr.right is not None:
                q.append(curr.right)

        level += 1

    return level

if __name__ == '__main__':
    # Representation of the input tree:
    #        10
    #       /  \
    #     20    30
    #      \   \
    #       40    60
    #             /
    #           2

    root = Node(10)
    root.left = Node(20)
    root.right = Node(30)
    root.left.right = Node(40)
    root.right.right = Node(60)
    root.right.right.left = Node(2)

    print(maxLevel(root))
C#
using System;
using System.Collections.Generic;

public class Node {
    public int data;
    public Node left;
    public Node right;

    public Node(int val)
    {
        data = val;
        left = right = null;
    }
}

public class GFG {
    public static int maxLevel(Node root)
    {
        if (root == null)
            return 0;

        // Initialize a queue for level order traversal.
        Queue<Node> q = new Queue<Node>();
        q.Enqueue(root);

        int level = 0;

        // Traverse the tree level by level.
        while (q.Count > 0) {
            int levelSize = q.Count;

            // Process all nodes at the current level.
            for (int i = 0; i < levelSize; i++) {
                Node curr = q.Dequeue();

                // Add the left child to the queue.
                if (curr.left != null)
                    q.Enqueue(curr.left);

                // Add the right child to the queue.
                if (curr.right != null)
                    q.Enqueue(curr.right);
            }

            // Move to the next level.
            level++;
        }

        return level;
    }

    public static void Main()
    {
        // Representation of the input tree:
        //        10
        //       /  \
        //     20    30
        //      \    \
        //       40    60
        //             /
        //            2

        Node root = new Node(10);
        root.left = new Node(20);
        root.right = new Node(30);
        root.left.right = new Node(40);
        root.right.right = new Node(60);
        root.right.right.left = new Node(2);

        Console.WriteLine(maxLevel(root));
    }
}
JavaScript
class Node {
    constructor(val)
    {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

function maxLevel(root)
{
    if (root === null) {
        return 0;
    }

    // Initialize a queue for level order traversal.
    let q = [];
    q.push(root);

    let level = 0;

    // Traverse the tree level by level.
    while (q.length > 0) {
        let levelSize = q.length;

        // Process all nodes at the current level.
        for (let i = 0; i < levelSize; i++) {
            let curr = q.shift();

            // Add the left child to the queue.
            if (curr.left !== null) {
                q.push(curr.left);
            }

            // Add the right child to the queue.
            if (curr.right !== null) {
                q.push(curr.right);
            }
        }

        // Move to the next level.
        level++;
    }

    return level;
}

// Driver Code
// Representation of the input tree:
//         10
//        /  \
//      20    30
//       \    \
//        40   60
//              /
//             2

let root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.right = new Node(40);
root.right.right = new Node(60);
root.right.right.left = new Node(2);

console.log(maxLevel(root));

Output
4
Comment