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
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.
Using 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:
Perform BFS and store each node’s parent: parent[1] = -1, parent[2] = 1, parent[3] = 1, parent[4] = 2, parent[5] = 2.
Start from given node = 4 with k = 2.
First move: go to parent from 4 to 2, now k = 1.
Second move: go to parent from 2 to 1, now k = 0.
When k becomes 0, current node 1 is the k-th ancestor.
C++
#include<iostream>#include<queue>#include<cstring>usingnamespacestd;// A Binary Tree Node structNode{intdata;Node*left,*right;Node(intdata){this->data=data;this->left=nullptr;this->right=nullptr;}};// function to build map of parentsvoidbuildParentMap(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);}}}intkthAncestor(Node*root,intk,intnode){// stores immediate parent (1st ancestor) of each nodeunordered_map<int,int>parent;buildParentMap(root,parent);while(node!=-1&&k>0){node=parent[node];k--;}// return k-th ancestorreturnnode;}intmain(){// Create binary tree Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->left->left=newNode(4);root->left->right=newNode(5);intk=2;intnode=5;// print kth ancestor of given node cout<<kthAncestor(root,k,node);return0;}
Java
importjava.util.Queue;importjava.util.LinkedList;importjava.util.HashMap;classGfG{// A Binary Tree Node staticclassNode{intdata;Nodeleft,right;Node(intdata){this.data=data;this.left=null;this.right=null;}}// function to build map of parentsstaticvoidbuildParentMap(Noderoot,HashMap<Integer,Integer>parent){parent.put(root.data,-1);// level order traversal to // store immediate parent (1st ancestor)Queue<Node>q=newLinkedList<>();q.add(root);while(!q.isEmpty()){Nodetemp=q.peek();q.remove();if(temp.left!=null){parent.put(temp.left.data,temp.data);q.add(temp.left);}if(temp.right!=null){parent.put(temp.right.data,temp.data);q.add(temp.right);}}}// function to calculate Kth ancestor staticintkthAncestor(Noderoot,intk,intnode){// stores immediate parent (1st ancestor) of each nodeHashMap<Integer,Integer>parent=newHashMap<>();buildParentMap(root,parent);while(node!=-1&&k>0){node=parent.get(node);k--;}// return k-th ancestor returnnode;}publicstaticvoidmain(String[]args){// Create binary tree Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);intk=2;intnode=5;// print kth ancestor of given node System.out.println(kthAncestor(root,k,node));}}
Python
# A Binary Tree Node classNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# function to build map of parentsdefbuildParentMap(root,parent):parent[root.data]=-1# level order traversal to # store immediate parent (1st ancestor)q=[]q.append(root)whilelen(q):temp=q.pop(0)iftemp.left:parent[temp.left.data]=temp.dataq.append(temp.left)iftemp.right:parent[temp.right.data]=temp.dataq.append(temp.right)# function to calculate Kth ancestor defkthAncestor(root,k,node):# stores immediate parent (1st ancestor) of each nodeparent={}buildParentMap(root,parent)whilenode!=-1andk>0:node=parent.get(node)k-=1# return k-th ancestorreturnnodeif__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=2node=5# print kth ancestor of given node print(kthAncestor(root,k,node))
C#
usingSystem;usingSystem.Collections.Generic;classGfG{// A Binary Tree Node publicclassNode{publicintdata;publicNodeleft,right;publicNode(intdata){this.data=data;this.left=null;this.right=null;}}// function to build map of parentsstaticvoidbuildParentMap(Noderoot,Dictionary<int,int>parent){parent[root.data]=-1;// level order traversal to // store immediate parent (1st ancestor)Queue<Node>q=newQueue<Node>();q.Enqueue(root);while(q.Count!=0){Nodetemp=q.Dequeue();if(temp.left!=null){parent[temp.left.data]=temp.data;q.Enqueue(temp.left);}if(temp.right!=null){parent[temp.right.data]=temp.data;q.Enqueue(temp.right);}}}// function to calculate Kth ancestor staticintkthAncestor(Noderoot,intk,intnode){// stores immediate parent (1st ancestor) of each nodeDictionary<int,int>parent=newDictionary<int,int>();buildParentMap(root,parent);while(node!=-1&&k>0){node=parent[node];k--;}// return k-th ancestor returnnode;}publicstaticvoidMain(String[]args){// Create binary tree Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);intk=2;intnode=5;// print kth ancestor of given node Console.WriteLine(kthAncestor(root,k,node));}}
JavaScript
// A Binary Tree Node classNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// function to build map of parentsfunctionbuildParentMap(root,parent){parent[root.data]=-1;// level order traversal to // store immediate parent (1st ancestor)varq=[];q.push(root);while(q.length!=0){vartemp=q.shift();if(temp.left!=null){parent[temp.left.data]=temp.data;q.push(temp.left);}if(temp.right!=null){parent[temp.right.data]=temp.data;q.push(temp.right);}}}// function to calculate Kth ancestor functionkthAncestor(root,k,node){// stores immediate parent (1st ancestor) of each nodevarparent={};buildParentMap(root,parent);while(node!=-1&&k>0){node=parent[node];k--;}// return k-th ancestor returnnode;}// Driver code // Create binary tree varroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);vark=2;varnode=5;// print kth ancestor of given node console.log(kthAncestor(root,k,node));
Output
1
Using Recursive Backtracking - 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 backtracking 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:
First, check if k == 0. If yes, return the current node as the ancestor; otherwise, move one level up and reduce k by 1.
Initially, k = 2. Start searching for node 8.
At node 8: k != 0 (k = 2), so reduce k = 1 and move up to its parent 7.
At node 7: k != 0 (k = 1), so reduce k = 0 and move up to its parent 4.
At node 4: now k == 0, so return 4 as the k-th ancestor.
C++
#include<iostream>usingnamespacestd;// A Binary Tree NodestructNode{intdata;Node*left,*right;Node(intdata){this->data=data;this->left=this->right=nullptr;}};// Program to find kth ancestorboolfindAncestor(Node*root,intnode,int&k,int&ans){if(root==nullptr)returnfalse;// Element whose ancestor is to be searchedif(root->data==node){//reduce count by 1k=k-1;returntrue;}// Checking in left sideboolleft=findAncestor(root->left,node,k,ans);// Similarly Checking in right sideboolright=findAncestor(root->right,node,k,ans);if(left||right){if(k==0){// If count = 0 i.e. element is foundans=root->data;returnfalse;}// if count !=0 i.e. this is not the // ancestor we are searching for // so decrement countk=k-1;returntrue;}returnfalse;}intkthAncestor(Node*root,intk,intnode){intans=-1;findAncestor(root,node,k,ans);returnans;}intmain(){// Create binary tree Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->left->left=newNode(4);root->left->right=newNode(5);intk=2;intnode=5;// print kth ancestor of given node cout<<kthAncestor(root,k,node);return0;}
Java
classGfG{// A Binary Tree NodestaticclassNode{intdata;Nodeleft,right;Node(intdata){this.data=data;this.left=this.right=null;}}// Program to find kth ancestorstaticbooleanfindAncestor(Noderoot,intnode,int[]k,int[]ans){if(root==null)returnfalse;// Element whose ancestor is to be searchedif(root.data==node){//reduce count by 1k[0]=k[0]-1;returntrue;}// Checking in left sidebooleanleft=findAncestor(root.left,node,k,ans);// Similarly Checking in right sidebooleanright=findAncestor(root.right,node,k,ans);if(left||right){if(k[0]==0){// If count = 0 i.e. element is foundans[0]=root.data;returnfalse;}// if count !=0 i.e. this is not the // ancestor we are searching for // so decrement countk[0]=k[0]-1;returntrue;}returnfalse;}staticintkthAncestor(Noderoot,intk,intnode){int[]ans=newint[]{-1};int[]kArr=newint[]{k};findAncestor(root,node,kArr,ans);returnans[0];}publicstaticvoidmain(String[]args){// Create binary tree Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);intk=2;intnode=5;// print kth ancestor of given node System.out.println(kthAncestor(root,k,node));}}
Python
# A Binary Tree NodeclassNode:def__init__(self,data):self.data=dataself.left=self.right=None# Program to find kth ancestordeffindAncestor(root,node,k,ans):ifrootisNone:returnFalse# Element whose ancestor is to be searchedifroot.data==node:#reduce count by 1k[0]=k[0]-1returnTrue# Checking in left sideleft=findAncestor(root.left,node,k,ans)# Similarly Checking in right sideright=findAncestor(root.right,node,k,ans)ifleftorright:ifk[0]==0:# If count = 0 i.e. element is foundans[0]=root.datareturnFalse# if count !=0 i.e. this is not the # ancestor we are searching for # so decrement countk[0]=k[0]-1returnTruereturnFalsedefkthAncestor(root,k,node):ans=[-1]kArr=[k]findAncestor(root,node,kArr,ans)returnans[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=2node=5# print kth ancestor of given node print(kthAncestor(root,k,node))
C#
usingSystem;// A Binary Tree NodepublicclassNode{publicintdata;publicNodeleft,right;publicNode(intdata){this.data=data;this.left=this.right=null;}}classGfG{// Program to find kth ancestorstaticboolfindAncestor(Noderoot,intnode,refintk,refintans){if(root==null)returnfalse;// Element whose ancestor is to be searchedif(root.data==node){//reduce count by 1k=k-1;returntrue;}// Checking in left sideboolleft=findAncestor(root.left,node,refk,refans);// Similarly Checking in right sideboolright=findAncestor(root.right,node,refk,refans);if(left||right){if(k==0){// If count = 0 i.e. element is foundans=root.data;returnfalse;}// if count !=0 i.e. this is not the // ancestor we are searching for // so decrement countk=k-1;returntrue;}returnfalse;}staticintkthAncestor(Noderoot,intk,intnode){intans=-1;findAncestor(root,node,refk,refans);returnans;}staticpublicvoidMain(){// Create binary tree Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);intk=2;intnode=5;// print kth ancestor of given node Console.WriteLine(kthAncestor(root,k,node));}}
JavaScript
// A Binary Tree NodeclassNode{constructor(data){this.data=data;this.left=this.right=null;}}// Program to find kth ancestorfunctionfindAncestor(root,node,k,ans){if(root===null)returnfalse;// Element whose ancestor is to be searchedif(root.data===node){//reduce count by 1k[0]=k[0]-1;returntrue;}// Checking in left sideletleft=findAncestor(root.left,node,k,ans);// Similarly Checking in right sideletright=findAncestor(root.right,node,k,ans);if(left||right){if(k[0]===0){// If count = 0 i.e. element is foundans[0]=root.data;returnfalse;}// if count !=0 i.e. this is not the // ancestor we are searching for // so decrement countk[0]=k[0]-1;returntrue;}returnfalse;}functionkthAncestor(root,k,node){letans=[-1];letkArr=[k];findAncestor(root,node,kArr,ans);returnans[0];}// Driver code// Create binary tree letroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);letk=2;letnode=5;// print kth ancestor of given node console.log(kthAncestor(root,k,node));