K-th Ancestor in a Binary Tree

Last Updated : 17 Oct, 2026

Given a binary tree of size n, along with a node and a positive integer k, find the k-th ancestor of the given node in the binary tree. If such an ancestor does not exist, return -1.

Note: It is guaranteed that the node exists in the tree and all the nodes of the tree have distinct values.

Examples:

Input: k = 2, node = 4

blobid0_1745302099

Output: 1
Explanation: Since, k is 2 and node is 4, so we first need to locate the node and look k times its ancestors. In this case, node 4 has 1 as its 2nd ancestor, which is the root of the tree.

Input: k=1, node=3
Output: 1
Explanation: k = 1 and node = 3, k-th ancestor of node 3 is 1.

Try It Yourself
redirect icon

Hash Map & Level Order Traversal - O(n) Time and O(n) Space

This idea is to find the k-th ancestor by first storing the parent of every node in a map using level order traversal (BFS). Once we know each node’s direct parent, we can easily move upward from the given node step-by-step. By repeating this process k times (or until the root is reached), we reach the required k-th ancestor efficiently.

Once the parent map is built, the k-th ancestor can be found as:

  • 1st ancestor = parent[i]
  • 2nd ancestor = parent[parent[i]]
  • 3rd ancestor = parent[parent[parent[i]]]
  • …
  • k-th ancestor = applying parent[] k times on node i

Consider the tree given below:

blobid0_1745302099
  1. Perform BFS and store each node’s parent:
    parent[1] = -1, parent[2] = 1, parent[3] = 1, parent[4] = 2, parent[5] = 2.
  2. Start from given node = 4 with k = 2.
  3. First move: go to parent from 4 to 2, now k = 1.
  4. Second move: go to parent from 2 to 1, now k = 0.
  5. When k becomes 0, current node 1 is the k-th ancestor.
C++
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
 
// A Binary Tree Node 
struct Node 
{ 
    int data; 
    Node *left, *right; 
    
    Node(int data) {
        this->data = data;
        this->left = nullptr;
        this->right = nullptr;
    }
};

// function to build map of parents
void buildParentMap(Node *root, 
                    unordered_map<int, int> &parent) 
{ 
    parent[root->data] = -1; 

    // level order traversal to 
    // store immediate parent (1st ancestor)
    queue<Node*> q; 
    q.push(root); 

    while(!q.empty()) 
    { 
        Node* temp = q.front(); 
        q.pop(); 

        if (temp->left != nullptr) 
        { 
            parent[temp->left->data] = temp->data; 
            q.push(temp->left); 
        } 

        if (temp->right != nullptr) 
        { 
            parent[temp->right->data] = temp->data; 
            q.push(temp->right); 
        } 
    } 
}

int kthAncestor(Node *root, int k, int node) 
{ 
    // stores immediate parent (1st ancestor) of each node
    unordered_map<int, int> parent;

    buildParentMap(root, parent); 

    while (node != -1 && k > 0) 
    { 
        node = parent[node]; 
        k--;
    } 

    // return k-th ancestor
    return node; 
}

int main() 
{ 
    // Create binary tree  
    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); 

    int k = 2; 
    int node = 5; 

    // print kth ancestor of given node 
    cout << kthAncestor(root, k, node); 
    return 0; 
}
Java
import java.util.Queue;
import java.util.LinkedList;
import java.util.HashMap;

class Node {
    int data;
    Node left, right;

    Node(int data) {
        this.data = data;
    }
}

class GFG {
    static void buildParentMap(Node root, HashMap<Integer, Integer> parent) {
        if (root == null)
            return;

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

        // Store parent of each node
        while (!q.isEmpty()) {
            Node curr = q.poll();

            if (curr.left != null) {
                parent.put(curr.left.data, curr.data);
                q.add(curr.left);
            }

            if (curr.right != null) {
                parent.put(curr.right.data, curr.data);
                q.add(curr.right);
            }
        }
    }

    static int kthAncestor(Node root, int k, int node) {
        HashMap<Integer, Integer> parent = new HashMap<>();
        buildParentMap(root, parent);

        // Move k times towards the parent
        while (k > 0 && parent.containsKey(node)) {
            node = parent.get(node);
            k--;
        }

        return k == 0 ? node : -1;
    }

    public static void main(String[] args) {
        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);

        int k = 2;
        int node = 5;

        System.out.println(kthAncestor(root, k, node));
    }
}
Python
# A Binary Tree Node 
class Node: 
    
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

# function to build map of parents
def buildParentMap(root, parent):
    
    parent[root.data] = -1

    # level order traversal to 
    # store immediate parent (1st ancestor)
    q = []
    q.append(root)

    while len(q):
        temp = q.pop(0)

        if temp.left:
            parent[temp.left.data] = temp.data
            q.append(temp.left)

        if temp.right:
            parent[temp.right.data] = temp.data
            q.append(temp.right)

# function to calculate Kth ancestor 
def kthAncestor(root, k, node):
    
    # stores immediate parent (1st ancestor) of each node
    parent = {}

    buildParentMap(root, parent)

    while node != -1 and k > 0:
        node = parent.get(node)
        k -= 1

    # return k-th ancestor
    return node

if __name__ == '__main__':

    # Create binary tree 
    root = Node(1)
    root.left = Node(2)
    root.right = Node(3)
    root.left.left = Node(4)
    root.left.right = Node(5)
    
    k = 2
    node = 5

    # print kth ancestor of given node 
    print(kthAncestor(root, k, node))
C#
using System;
using System.Collections.Generic;

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

    public Node(int data)
    {
        this.data = data;
    }
}

class GFG
{
    static void buildParentMap(Node root, Dictionary<int, int> parent)
    {
        if (root == null)
            return;

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

        // Store parent of each node
        while (q.Count > 0)
        {
            Node curr = q.Dequeue();

            if (curr.left != null)
            {
                parent[curr.left.data] = curr.data;
                q.Enqueue(curr.left);
            }

            if (curr.right != null)
            {
                parent[curr.right.data] = curr.data;
                q.Enqueue(curr.right);
            }
        }
    }

    static int kthAncestor(Node root, int k, int node)
    {
        Dictionary<int, int> parent = new Dictionary<int, int>();
        buildParentMap(root, parent);

        // Move k times towards the parent
        while (k > 0 && parent.ContainsKey(node))
        {
            node = parent[node];
            k--;
        }

        return k == 0 ? node : -1;
    }

    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);

        int k = 2;
        int node = 5;

        Console.WriteLine(kthAncestor(root, k, node));
    }
}
JavaScript
class Node {
    constructor(data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

// Build a map of each node and its parent
function buildParentMap(root, parent) {
    parent.set(root.data, -1);

    let queue = [root];
    let front = 0;

    while (front < queue.length) {
        let temp = queue[front++];

        if (temp.left !== null) {
            parent.set(temp.left.data, temp.data);
            queue.push(temp.left);
        }

        if (temp.right !== null) {
            parent.set(temp.right.data, temp.data);
            queue.push(temp.right);
        }
    }
}

// Find the kth ancestor of the given node
function kthAncestor(root, k, node) {
    let parent = new Map();

    buildParentMap(root, parent);

    while (node !== -1 && k > 0) {
        node = parent.get(node);
        k--;
    }

    return node;
}

// Driver code
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);

let k = 2;
let node = 5;

console.log(kthAncestor(root, k, node));

Output
1

Recursive Trace Back - O(n) Time and O(n) Space

The idea is to traverse the tree using recursion to first locate the target node and then trace back toward the root.

During this trace back phase, we decrease the value of k at each step as we move up through its ancestors. When k becomes 0, the current node at that point is the k-th ancestor.

Consider the tree given below:

frame_3207
  1. First, check if k == 0. If yes, return the current node as the ancestor; otherwise, move one level up and reduce k by 1.
  2. Initially, k = 2. Start searching for node 8.
  3. At node 8: k != 0 (k = 2), so reduce k = 1 and move up to its parent 7.
  4. At node 7: k != 0 (k = 1), so reduce k = 0 and move up to its parent 4.
  5. At node 4: now k == 0, so return 4 as the k-th ancestor.
C++
#include <iostream>
using namespace std;

// A Binary Tree Node
struct Node
{
    int data;
    Node *left, *right;

    Node(int data)
    {
        this->data = data;
        this->left = this->right = nullptr;
    }
};

// Program to find kth ancestor
bool findAncestor(Node* root, int node, int &k, int &ans)
{
    if(root == nullptr)
        return false;
  
    // Element whose ancestor is to be searched
    if(root->data == node)
    {
        //reduce count by 1
        k = k - 1;
        return true;
    }

    // Checking in left side
    bool left = findAncestor(root->left, node, k, ans);

    // Similarly Checking in right side
    bool right = findAncestor(root->right, node, k, ans);

    if(left || right)
    {
        if(k == 0)
        {
            // If count = 0 i.e. element is found
            ans = root->data;
            return false;
        }
      
        // if count !=0 i.e. this is not the 
        // ancestor we are searching for 
        // so decrement count
        k = k - 1;
        return true;
    }

    return false;
}

int kthAncestor(Node *root, int k, int node)
{
    int ans = -1;
    findAncestor(root, node, k, ans);
    return ans;
}

int main() 
{ 
    // Create binary tree 
    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); 

    int k = 2; 
    int node = 5; 

    // print kth ancestor of given node 
    cout << kthAncestor(root, k, node); 
    return 0; 
}
Java
class Node {
    int data;
    Node left, right;

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

class GFG {

    static boolean findAncestor(Node root, int node, int[] k, int[] ans) {
        if (root == null)
            return false;

        // Check if current node is the target
        if (root.data == node) {
            k[0]--;
            return true;
        }

        boolean left = findAncestor(root.left, node, k, ans);
        boolean right = findAncestor(root.right, node, k, ans);

        if (left || right) {
            if (k[0] == 0) {
                ans[0] = root.data;
                return false;
            }

            k[0]--;
            return true;
        }

        return false;
    }

    static int kthAncestor(Node root, int k, int node) {
        int[] ans = {-1};
        int[] kArr = {k};

        // Find the kth ancestor recursively
        findAncestor(root, node, kArr, ans);

        return ans[0];
    }

    public static void main(String[] args) {
        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);

        int k = 2;
        int node = 5;

        System.out.println(kthAncestor(root, k, node));
    }
}
Python
# A Binary Tree Node
class Node:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None

# Program to find kth ancestor
def findAncestor(root, node, k, ans):
    if root is None:
        return False
  
    # Element whose ancestor is to be searched
    if root.data == node:
        
        #reduce count by 1
        k[0] = k[0] - 1
        return True

    # Checking in left side
    left = findAncestor(root.left, node, k, ans)

    # Similarly Checking in right side
    right = findAncestor(root.right, node, k, ans)

    if left or right:
        if k[0] == 0:
            
            # If count = 0 i.e. element is found
            ans[0] = root.data
            return False
      
        # if count !=0 i.e. this is not the 
        # ancestor we are searching for 
        # so decrement count
        k[0] = k[0] - 1
        return True

    return False

def kthAncestor(root, k, node):
    ans = [-1]
    kArr = [k]

    findAncestor(root, node, kArr, ans)
    return ans[0]

if __name__=="__main__":
    
    # Create binary tree 
    root = Node(1)
    root.left = Node(2)
    root.right = Node(3)
    root.left.left = Node(4)
    root.left.right = Node(5)
    
    k = 2
    node = 5

    # print kth ancestor of given node 
    print(kthAncestor(root, k, node))
C#
using System;

// A Binary Tree Node
public class Node
{
    public int data;
    public Node left, right;

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

class GfG
{
    static bool findAncestor(Node root, int node, ref int k, ref int ans)
    {
        if (root == null)
            return false;

        // Check if current node is the target
        if (root.data == node)
        {
            k--;
            return true;
        }

        bool left = findAncestor(root.left, node, ref k, ref ans);
        bool right = findAncestor(root.right, node, ref k, ref ans);

        if (left || right)
        {
            if (k == 0)
            {
                ans = root.data;
                return false;
            }

            k--;
            return true;
        }

        return false;
    }

    static int kthAncestor(Node root, int k, int node)
    {
        int ans = -1;

        // Find the kth ancestor recursively
        findAncestor(root, node, ref k, ref ans);

        return ans;
    }

    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);

        int k = 2;
        int node = 5;

        Console.WriteLine(kthAncestor(root, k, node));
    }
}
JavaScript
// A Binary Tree Node
class Node {
    constructor(data) {
        this.data = data;
        this.left = this.right = null;
    }
}

// Program to find kth ancestor
function findAncestor(root, node, k, ans) {
    if (root === null)
        return false;
  
    // Element whose ancestor is to be searched
    if (root.data === node) {
        //reduce count by 1
        k[0] = k[0] - 1;
        return true;
    }

    // Checking in left side
    let left = findAncestor(root.left, node, k, ans);

    // Similarly Checking in right side
    let right = findAncestor(root.right, node, k, ans);

    if (left || right) {
        if (k[0] === 0) {
            // If count = 0 i.e. element is found
            ans[0] = root.data;
            return false;
        }
      
        // if count !=0 i.e. this is not the 
        // ancestor we are searching for 
        // so decrement count
        k[0] = k[0] - 1;
        return true;
    }

    return false;
}

function kthAncestor(root, k, node) {
    let ans = [-1];
    let kArr = [k];

    findAncestor(root, node, kArr, ans);
    return ans[0];
}

// Driver code
// Create binary tree 
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);

let k = 2;
let node = 5;

// print kth ancestor of given node 
console.log(kthAncestor(root, k, node));

Output
1
Comment