Leftmost and Rightmost of all Levels in a Binary Tree

Last Updated : 9 May, 2026

Given the root of a binary tree, find the corner nodes from root to the last level. The corner nodes are the leftmost and rightmost nodes at each level of the binary tree.

Examples:

Input:

2056957843

Output: 1 2 3 4 7
Explanation:
Corners at level 0: 1
Corners at level 1: 2 3
Corners at level 2: 4 7

Input :

2056957844

Output : 10 20 30 40 60
Explanation :
Corners at level 0: 10
Corners at level 1: 20 30
Corners at level 2: 40 60

Try It Yourself
redirect icon

Using Recursive Approach - O(n) Time and O(n) Space

The idea is to use recursion and track the level of each node. For every level, the first visited node is stored as the leftmost, and the last visited node is updated as the rightmost. Finally, we print both for each level (avoiding duplicates).

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

// Structure of a Binary Tree Node
class Node
{
  public:
    int data;
    Node *left;
    Node *right;

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

// Function to perform DFS traversal and store nodes level-wise
void dfs(Node *root, int level, vector<vector<Node *>> &levels)
{
    // Base case
    if (root == nullptr)
        return;

    // If visiting this level for the first time
    if (level == levels.size())
    {
        levels.push_back({});
    }

    // Store current node at its level
    levels[level].push_back(root);

    // Recur for left and right subtree
    dfs(root->left, level + 1, levels);
    dfs(root->right, level + 1, levels);
}

// Function to return corner nodes of binary tree
vector<int> getCorner(Node *root)
{
    vector<int> ans;

    // Edge case: empty tree
    if (root == nullptr)
        return ans;

    // Vector to store nodes level-wise
    vector<vector<Node *>> levels;

    // Fill levels using DFS
    dfs(root, 0, levels);

    // Traverse each level
    for (auto &level : levels)
    {
        // Add leftmost node
        ans.push_back(level.front()->data);

        // Add rightmost node if different
        if (level.front() != level.back())
        {
            ans.push_back(level.back()->data);
        }
    }

    return ans;
}

// Driver code
int main()
{
    // Constructing the tree:
    //        1
    //      /   \
    //     2     3
    //    / \   / \
    //   4   5 6   7

    Node *root = new Node(1);
    root->left = new Node(2);
    root->right = new Node(3);
    root->left->left = new Node(4);
    root->left->right = new Node(5);
    root->right->left = new Node(6);
    root->right->right = new Node(7);

    // Get corner nodes
    vector<int> result = getCorner(root);

    // Print result
    for (int x : result)
        cout << x << " ";

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

// Structure of a Binary Tree Node
class Node
{
    public int data;
    public Node left;
    public Node right;

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

class GfG
{
    // Function to perform DFS traversal and store nodes level-wise
    public static void dfs(Node root, int level, ArrayList<ArrayList<Node>> levels)
    {
        // Base case
        if (root == null)
            return;

        // If visiting this level for the first time
        if (level == levels.size())
        {
            levels.add(new ArrayList<>());
        }

        // Store current node at its level
        levels.get(level).add(root);

        // Recur for left and right subtree
        dfs(root.left, level + 1, levels);
        dfs(root.right, level + 1, levels);
    }

    // Function to return corner nodes of binary tree
    public static ArrayList<Integer> getCorner(Node root)
    {
        ArrayList<Integer> ans = new ArrayList<>();

        // Edge case: empty tree
        if (root == null)
            return ans;

        // Vector to store nodes level-wise
        ArrayList<ArrayList<Node>> levels = new ArrayList<>();

        // Fill levels using DFS
        dfs(root, 0, levels);

        // Traverse each level
        for (ArrayList<Node> level : levels)
        {
            // Add leftmost node
            ans.add(level.get(0).data);

            // Add rightmost node if different
            if (level.get(0) != level.get(level.size() - 1))
            {
                ans.add(level.get(level.size() - 1).data);
            }
        }

        return ans;
    }

    public static void main(String[] args)
    {
        // Constructing the tree:
        //        1
        //      /   \
        //     2     3
        //    / \   / \
        //   4   5 6   7

        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);
        root.right.left = new Node(6);
        root.right.right = new Node(7);

        // Get corner nodes
        ArrayList<Integer> result = getCorner(root);

        // Print result
        for (int x : result)
            System.out.print(x + " ");
    }
}
Python
# Structure of a Binary Tree Node
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

# Function to perform DFS traversal and store nodes level-wise
def dfs(root, level, levels):
    # Base case
    if root is None:
        return

    # If visiting this level for the first time
    if level == len(levels):
        levels.append([])

    # Store current node at its level
    levels[level].append(root)

    # Recur for left and right subtree
    dfs(root.left, level + 1, levels)
    dfs(root.right, level + 1, levels)

# Function to return corner nodes of binary tree
def getCorner(root):
    ans = []

    # Edge case: empty tree
    if root is None:
        return ans

    # List to store nodes level-wise
    levels = []

    # Fill levels using DFS
    dfs(root, 0, levels)

    # Traverse each level
    for level in levels:
        # Add leftmost node
        ans.append(level[0].data)

        # Add rightmost node if different
        if level[0]!= level[-1]:
            ans.append(level[-1].data)

    return ans

# Driver code
if __name__ == "__main__":
    # Constructing the tree:
    #        1
    #      /   \
    #     2     3
    #    / \   / \\
    #   4   5 6   7

    root = Node(1)
    root.left = Node(2)
    root.right = Node(3)
    root.left.left = Node(4)
    root.left.right = Node(5)
    root.right.left = Node(6)
    root.right.right = Node(7)

    # Get corner nodes
    result = getCorner(root)

    # Print result
    for x in result:
        print(x, end=" ")
C#
using System;
using System.Collections.Generic;

// Structure of a Binary Tree Node
class Node
{
    public int data;
    public Node left;
    public Node right;

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

class GfG
{
    // Function to perform DFS traversal and store nodes level-wise
    public void dfs(Node root, int level, List<List<Node>> levels)
    {
        // Base case
        if (root == null)
            return;

        // If visiting this level for the first time
        if (level == levels.Count)
        {
            levels.Add(new List<Node>());
        }

        // Store current node at its level
        levels[level].Add(root);

        // Recur for left and right subtree
        dfs(root.left, level + 1, levels);
        dfs(root.right, level + 1, levels);
    }

    // Function to return corner nodes of binary tree
    public List<int> getCorner(Node root)
    {
        List<int> ans = new List<int>();

        // Edge case: empty tree
        if (root == null)
            return ans;

        // Vector to store nodes level-wise
        List<List<Node>> levels = new List<List<Node>>();

        // Fill levels using DFS
        dfs(root, 0, levels);

        // Traverse each level
        foreach (var level in levels)
        {
            // Add leftmost node
            ans.Add(level[0].data);

            // Add rightmost node if different
            if (level[0] != level[level.Count - 1])
            {
                ans.Add(level[level.Count - 1].data);
            }
        }

        return ans;
    }

    public static void Main()
    {
        // Constructing the tree:
        //        1
        //      /   \
        //     2     3
        //    / \   / \
        //   4   5 6   7

        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.left.right = new Node(5);
        root.right.left = new Node(6);
        root.right.right = new Node(7);

        // Create object
        GfG obj = new GfG();

        // Get corner nodes
        List<int> result = obj.getCorner(root);

        // Print result
        foreach (int x in result)
            Console.Write(x + " ");
    }
}
JavaScript
// Structure of a Binary Tree Node
class Node {
    constructor(val)
    {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

// Function to perform DFS traversal and store nodes
// level-wise
function dfs(root, level, levels)
{
    // Base case
    if (root === null)
        return;

    // If visiting this level for the first time
    if (level === levels.length) {
        levels.push([]);
    }

    // Store current node at its level
    levels[level].push(root);

    // Recur for left and right subtree
    dfs(root.left, level + 1, levels);
    dfs(root.right, level + 1, levels);
}

// Function to return corner nodes of binary tree
function getCorner(root)
{
    let ans = [];

    // Edge case: empty tree
    if (root === null)
        return ans;

    // Vector to store nodes level-wise
    let levels = [];

    // Fill levels using DFS
    dfs(root, 0, levels);

    // Traverse each level
    for (let level of levels) {
        // Add leftmost node
        ans.push(level[0].data);

        // Add rightmost node if different
        if (level[0] !== level[level.length - 1]) {
            ans.push(level[level.length - 1].data);
        }
    }

    return ans;
}


// Constructing the tree:
//        1
//      /   \
//     2     3
//    / \   / \
//   4   5 6   7

let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);


let result = getCorner(root);

console.log(result.join(" "));

Output
1 2 3 4 7 

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

The idea is to use Level Order Traversal. Every time we store the size of the queue in a variable n, which is the number of nodes at that level. For every level, we check whether the current node is the first (i.e node at index 0) and the node at the last index (i.e node at index n-1) If it is either of them, we print the value of that node.  

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

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

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

// A binary tree node has key, pointer to left
//   child and a pointer to right child
vector<int> getCorner(Node *root)
{

    vector<int> result;

    // Queue for level order traversal
    queue<Node *> q;

    // Push root node
    q.push(root);

    // Level order traversal
    while (!q.empty())
    {

        // Number of nodes at current level
        int n = q.size();

        for (int i = 0; i < n; i++)
        {

            // Get front node
            Node *temp = q.front();
            q.pop();

            // If leftmost or rightmost node of level
            if (i == 0 || i == n - 1)
                result.push_back(temp->data);

            // Push children
            if (temp->left != nullptr)
                q.push(temp->left);

            if (temp->right != nullptr)
                q.push(temp->right);
        }
    }

    return result;
}

// Driver Code
int main()
{

    // Constructing the tree:
    //        1
    //      /   \
    //     2     3
    //    / \   / \
    //   4   5 6   7

    Node *root = new Node(1);
    root->left = new Node(2);
    root->right = new Node(3);

    root->left->left = new Node(4);
    root->left->right = new Node(5);

    root->right->left = new Node(6);
    root->right->right = new Node(7);

    vector<int> ans = getCorner(root);

    for (int x : ans)
    cout << x << " ";

    return 0;
}
Java
import java.util.LinkedList;
import java.util.Queue;
import java.util.ArrayList;

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

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

public class GFG {

  // A binary tree node has key, pointer to left child and a pointer to right child
  public static ArrayList<Integer> getCorner(Node root) {
    ArrayList<Integer> result = new ArrayList<>();

    // Queue for level order traversal
    Queue<Node> q = new LinkedList<>();

    // Push root node
    q.add(root);

    // Level order traversal
    while (!q.isEmpty()) {

      // Number of nodes at current level
      int n = q.size();

      for (int i = 0; i < n; i++) {

        // Get front node
        Node temp = q.poll();

        // If leftmost or rightmost node of level
        if (i == 0 || i == n - 1)
          result.add(temp.data);

        // Push children
        if (temp.left!= null)
          q.add(temp.left);

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

    return result;
  }

  // Driver Code
  public static void main(String[] args) {

    // Constructing the tree:
    //        1
    //      /   \
    //     2     3
    //    / \   / \
    //   4   5 6   7

    Node root = new Node(1);
    root.left = new Node(2);
    root.right = new Node(3);

    root.left.left = new Node(4);
    root.left.right = new Node(5);

    root.right.left = new Node(6);
    root.right.right = new Node(7);

    ArrayList<Integer> ans = getCorner(root);

    for (int x : ans)
      System.out.print(x + " ");
  }
}
Python
from collections import deque


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

def getCorner(root):
    result = []

    # queue for level order traversal
    q = deque()

    # pushing root node
    q.append(root)

    # Do level order traversal of Binary Tree
    while q:
        # n is the number of nodes in current level
        n = len(q)

        for i in range(n):
            # dequeue the front node from the queue
            temp = q.popleft()

            # If it is leftmost or rightmost node of level
            if i == 0 or i == n - 1:
                result.append(temp.data)

            # push children
            if temp.left is not None:
                q.append(temp.left)
            if temp.right is not None:
                q.append(temp.right)

    return result


# Driver code
if __name__ == '__main__':

    root = Node(1)
    root.left = Node(2)
    root.right = Node(3)

    root.left.left = Node(4)
    root.left.right = Node(5)

    root.right.left = Node(6)
    root.right.right = Node(7)

    ans = getCorner(root)

    for x in ans:
        print(x, end=' ')
C#
using System;
using System.Collections.Generic;

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

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

public class GfG {
    
    public List<int> getCorner(Node root)
    {
        List<int> result = new List<int>();

        // Edge case
        if (root == null)
            return result;

        // Queue for level order traversal
        Queue<Node> q = new Queue<Node>();

        // pushing root node
        q.Enqueue(root);

        // Do level order traversal of Binary Tree
        while (q.Count > 0) {

            // n is the no of nodes in current Level
            int n = q.Count;

            for (int i = 0; i < n; i++) {

                // dequeue the front node from the queue
                Node temp = q.Dequeue();

                // If it is leftmost or rightmost corner
                if (i == 0 || i == n - 1)
                    result.Add(temp.data);

                // push children
                if (temp.left != null)
                    q.Enqueue(temp.left);

                if (temp.right != null)
                    q.Enqueue(temp.right);
            }
        }

        return result;
    }

    // Driver Code
    public static void Main()
    {
        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);

        root.left.left = new Node(4);
        root.left.right = new Node(5);

        root.right.left = new Node(6);
        root.right.right = new Node(7);

        GfG obj = new GfG(); 
        List<int> ans = obj.getCorner(root);

        foreach(int x in ans) 
            Console.Write(x + " ");
    }
}
JavaScript
class Node {
  constructor(data) {
    this.data = data;
    this.left = null;
    this.right = null;
  }
}

// A binary tree node has key, pointer to left
//   child and a pointer to right child
function getCorner(root) {

  const result = [];

  // Queue for level order traversal
  const q = [];

  // Push root node
  q.push(root);

  // Level order traversal
  while (q.length > 0) {

    // Number of nodes at current level
    const n = q.length;

    for (let i = 0; i < n; i++) {

      // Get front node
      const temp = q.shift();

      // If leftmost or rightmost node of level
      if (i === 0 || i === n - 1)
        result.push(temp.data);

      // Push children
      if (temp.left!== null)
        q.push(temp.left);

      if (temp.right!== null)
        q.push(temp.right);
    }
  }

  return result;
}

// Driver Code
{
  // Constructing the tree:
  //        1
  //      /   \
  //     2     3
  //    / \   / \
  //   4   5 6   7

  const root = new Node(1);
  root.left = new Node(2);
  root.right = new Node(3);

  root.left.left = new Node(4);
  root.left.right = new Node(5);

  root.right.left = new Node(6);
  root.right.right = new Node(7);

  const ans = getCorner(root);

  for (const x of ans)
    console.log(x);
}

Output
1 2 3 4 7 
Comment