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.
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;classNode{intdata;Nodeleft,right;Node(intdata){this.data=data;}}classGFG{staticvoidbuildParentMap(Noderoot,HashMap<Integer,Integer>parent){if(root==null)return;Queue<Node>q=newLinkedList<>();q.add(root);// Store parent of each nodewhile(!q.isEmpty()){Nodecurr=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);}}}staticintkthAncestor(Noderoot,intk,intnode){HashMap<Integer,Integer>parent=newHashMap<>();buildParentMap(root,parent);// Move k times towards the parentwhile(k>0&&parent.containsKey(node)){node=parent.get(node);k--;}returnk==0?node:-1;}publicstaticvoidmain(String[]args){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;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;publicclassNode{publicintdata;publicNodeleft,right;publicNode(intdata){this.data=data;}}classGFG{staticvoidbuildParentMap(Noderoot,Dictionary<int,int>parent){if(root==null)return;Queue<Node>q=newQueue<Node>();q.Enqueue(root);// Store parent of each nodewhile(q.Count>0){Nodecurr=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);}}}staticintkthAncestor(Noderoot,intk,intnode){Dictionary<int,int>parent=newDictionary<int,int>();buildParentMap(root,parent);// Move k times towards the parentwhile(k>0&&parent.ContainsKey(node)){node=parent[node];k--;}returnk==0?node:-1;}staticvoidMain(){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;Console.WriteLine(kthAncestor(root,k,node));}}
JavaScript
classNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// Build a map of each node and its parentfunctionbuildParentMap(root,parent){parent.set(root.data,-1);letqueue=[root];letfront=0;while(front<queue.length){lettemp=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 nodefunctionkthAncestor(root,k,node){letparent=newMap();buildParentMap(root,parent);while(node!==-1&&k>0){node=parent.get(node);k--;}returnnode;}// Driver codeletroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);letk=2;letnode=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:
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
classNode{intdata;Nodeleft,right;Node(intdata){this.data=data;this.left=this.right=null;}}classGFG{staticbooleanfindAncestor(Noderoot,intnode,int[]k,int[]ans){if(root==null)returnfalse;// Check if current node is the targetif(root.data==node){k[0]--;returntrue;}booleanleft=findAncestor(root.left,node,k,ans);booleanright=findAncestor(root.right,node,k,ans);if(left||right){if(k[0]==0){ans[0]=root.data;returnfalse;}k[0]--;returntrue;}returnfalse;}staticintkthAncestor(Noderoot,intk,intnode){int[]ans={-1};int[]kArr={k};// Find the kth ancestor recursivelyfindAncestor(root,node,kArr,ans);returnans[0];}publicstaticvoidmain(String[]args){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;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{staticboolfindAncestor(Noderoot,intnode,refintk,refintans){if(root==null)returnfalse;// Check if current node is the targetif(root.data==node){k--;returntrue;}boolleft=findAncestor(root.left,node,refk,refans);boolright=findAncestor(root.right,node,refk,refans);if(left||right){if(k==0){ans=root.data;returnfalse;}k--;returntrue;}returnfalse;}staticintkthAncestor(Noderoot,intk,intnode){intans=-1;// Find the kth ancestor recursivelyfindAncestor(root,node,refk,refans);returnans;}staticvoidMain(){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;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));