[Naive Approach] Pre-Order Recursion O(n) time and O(h) space
The core idea involves a recursive pre-order traversal of the binary tree. The function should return true if the current node's value matches the key. For each parent node, if either its left or right child returns true, the parent's value should be added to the result list.
C++
#include<iostream>#include<vector>usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intx){data=x;left=nullptr;right=nullptr;}};boolancestorsRecur(Node*root,intkey,vector<int>&res){// Base Caseif(root==nullptr)returnfalse;// If current node is key nodeif(root->data==key)returntrue;boolleft=ancestorsRecur(root->left,key,res);boolright=ancestorsRecur(root->right,key,res);// If current node is ancestor to key nodeif(left||right)res.push_back(root->data);returnleft||right;}vector<int>ancestors(Node*root,intkey){vector<int>res;// Perform pre-order traversalancestorsRecur(root,key,res);returnres;}intmain(){// Binary tree// 1// / \ // 2 3// / \ // 4 5// /// 7Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->left->left=newNode(4);root->left->right=newNode(5);root->left->left->left=newNode(7);intkey=7;vector<int>res=ancestors(root,key);for(autoval:res)cout<<val<<" ";cout<<endl;return0;}
Java
importjava.util.ArrayList;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}publicclassGFG{publicstaticbooleanancestorsRecur(Noderoot,intkey,ArrayList<Integer>res){// Base Caseif(root==null)returnfalse;// If current node is key nodeif(root.data==key)returntrue;booleanleft=ancestorsRecur(root.left,key,res);booleanright=ancestorsRecur(root.right,key,res);// If current node is ancestor to key nodeif(left||right)res.add(root.data);returnleft||right;}publicstaticArrayList<Integer>ancestors(Noderoot,intkey){ArrayList<Integer>res=newArrayList<>();// Perform pre-order traversalancestorsRecur(root,key,res);returnres;}publicstaticvoidmain(String[]args){// Binary tree// 1// / \// 2 3// / \// 4 5// /// 7Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.left.left.left=newNode(7);intkey=7;ArrayList<Integer>res=ancestors(root,key);for(intval:res)System.out.print(val+" ");System.out.println();}}
Python
classNode:def__init__(self,x):self.data=xself.left=Noneself.right=Nonedefancestors_recur(root,key,res):# Base CaseifrootisNone:returnFalse# If current node is key nodeifroot.data==key:returnTrueleft=ancestors_recur(root.left,key,res)right=ancestors_recur(root.right,key,res)# If current node is ancestor to key nodeifleftorright:res.append(root.data)returnleftorrightdefancestors(root,key):res=[]# Perform pre-order traversalancestors_recur(root,key,res)returnresif__name__=='__main__':# Binary tree# 1# / \# 2 3# / \# 4 5# /# 7root=Node(1)root.left=Node(2)root.right=Node(3)root.left.left=Node(4)root.left.right=Node(5)root.left.left.left=Node(7)key=7res=ancestors(root,key)forvalinres:print(val,end=' ')print()
C#
usingSystem;usingSystem.Collections.Generic;publicclassNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}publicclassGFG{publicstaticboolAncestorsRecur(Noderoot,intkey,List<int>res){// Base Caseif(root==null)returnfalse;// If current node is key nodeif(root.data==key)returntrue;boolleft=AncestorsRecur(root.left,key,res);boolright=AncestorsRecur(root.right,key,res);// If current node is ancestor to key nodeif(left||right)res.Add(root.data);returnleft||right;}publicstaticList<int>Ancestors(Noderoot,intkey){List<int>res=newList<int>();// Perform pre-order traversalAncestorsRecur(root,key,res);returnres;}publicstaticvoidMain(){// Binary tree// 1// / \// 2 3// / \// 4 5// /// 7Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.left.left.left=newNode(7);intkey=7;List<int>res=Ancestors(root,key);foreach(intvalinres)Console.Write(val+" ");Console.WriteLine();}}
JavaScript
classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}functionancestorsRecur(root,key,res){// Base Caseif(root===null)returnfalse;// If current node is key nodeif(root.data===key)returntrue;letleft=ancestorsRecur(root.left,key,res);letright=ancestorsRecur(root.right,key,res);// If current node is ancestor to key nodeif(left||right)res.push(root.data);returnleft||right;}functionancestors(root,key){letres=[];// Perform pre-order traversalancestorsRecur(root,key,res);returnres;}// Binary tree// 1// / \// 2 3// / \// 4 5// /// 7letroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.left.left.left=newNode(7);letkey=7;letres=ancestors(root,key);for(letvalofres)process.stdout.write(val+' ');console.log();
Output
4 2 1
Time Complexity: O(n) Auxiliary Space: O(h)
[Expected Approach] Post-Order Stack based Recursion O(n) time and O(h) space
The approach involves an iterative post-order traversal using a stack to track the path. When the target node is found, the remaining nodes in the stack represent its ancestors.
Note: While the overall Big O time complexity might be the same, this approach is faster due to early pruning and better space handling.
C++
#include<iostream>#include<vector>#include<stack>usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intx){data=x;left=nullptr;right=nullptr;}};vector<int>ancestors(Node*root,intkey){vector<int>res;if(root==nullptr)returnres;stack<Node*>st;Node*curr=root;Node*prev=nullptr;while(curr!=nullptr||!st.empty()){if(curr!=nullptr){st.push(curr);curr=curr->left;}else{Node*topNode=st.top();if(topNode->right!=nullptr&&prev!=topNode->right){curr=topNode->right;}else{if(topNode->data==key){// Found the key node, now all nodes// in stack are ancestorsst.pop();while(!st.empty()){res.push_back(st.top()->data);st.pop();}returnres;}prev=st.top();st.pop();}}}returnres;}intmain(){// Binary tree// 1// / \ // 2 3// / \ // 4 5// /// 7Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->left->left=newNode(4);root->left->right=newNode(5);root->left->left->left=newNode(7);intkey=7;vector<int>res=ancestors(root,key);for(autoval:res)cout<<val<<" ";cout<<endl;return0;}
Java
importjava.util.ArrayList;importjava.util.Stack;classNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGfG{staticArrayList<Integer>ancestors(Noderoot,intkey){ArrayList<Integer>res=newArrayList<>();if(root==null)returnres;Stack<Node>st=newStack<>();Nodecurr=root;Nodeprev=null;while(curr!=null||!st.empty()){if(curr!=null){st.push(curr);curr=curr.left;}else{NodetopNode=st.peek();if(topNode.right!=null&&prev!=topNode.right){curr=topNode.right;}else{if(topNode.data==key){// Found the key node, now all nodes// in stack are ancestorsst.pop();while(!st.empty()){res.add(st.peek().data);st.pop();}returnres;}prev=st.peek();st.pop();}}}returnres;}publicstaticvoidmain(String[]args){// Binary tree// 1// / \// 2 3// / \// 4 5// /// 7Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.left.left.left=newNode(7);intkey=7;ArrayList<Integer>res=ancestors(root,key);for(intval:res)System.out.print(val+" ");System.out.println();}}
Python
classNode:def__init__(self,x):self.data=xself.left=Noneself.right=Nonedefancestors(root,key):res=[]ifrootisNone:returnresst=[]curr=rootprev=NonewhilecurrisnotNoneorlen(st)>0:ifcurrisnotNone:st.append(curr)curr=curr.leftelse:topNode=st[-1]iftopNode.rightisnotNoneandprev!=topNode.right:curr=topNode.rightelse:iftopNode.data==key:# Found the key node, now all nodes# in stack are ancestorsst.pop()whilelen(st)>0:res.append(st[-1].data)st.pop()returnresprev=st[-1]st.pop()returnresif__name__=="__main__":# Binary tree# 1# / \# 2 3# / \# 4 5# /# 7root=Node(1)root.left=Node(2)root.right=Node(3)root.left.left=Node(4)root.left.right=Node(5)root.left.left.left=Node(7)key=7res=ancestors(root,key)forvalinres:print(val,end=" ")print()
C#
usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGfG{staticList<int>ancestors(Noderoot,intkey){List<int>res=newList<int>();if(root==null)returnres;Stack<Node>st=newStack<Node>();Nodecurr=root;Nodeprev=null;while(curr!=null||st.Count>0){if(curr!=null){st.Push(curr);curr=curr.left;}else{NodetopNode=st.Peek();if(topNode.right!=null&&prev!=topNode.right){curr=topNode.right;}else{if(topNode.data==key){// Found the key node, now all nodes// in stack are ancestorsst.Pop();while(st.Count>0){res.Add(st.Peek().data);st.Pop();}returnres;}prev=st.Peek();st.Pop();}}}returnres;}staticvoidMain(){// Binary tree// 1// / \// 2 3// / \// 4 5// /// 7Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.left.left.left=newNode(7);intkey=7;List<int>res=ancestors(root,key);foreach(intvalinres)Console.Write(val+" ");Console.WriteLine();}}
JavaScript
classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}functionancestors(root,key){letres=[];if(root===null)returnres;letst=[];letcurr=root;letprev=null;while(curr!==null||st.length>0){if(curr!==null){st.push(curr);curr=curr.left;}else{lettopNode=st[st.length-1];if(topNode.right!==null&&prev!==topNode.right){curr=topNode.right;}else{if(topNode.data===key){// Found the key node, now all nodes// in stack are ancestorsst.pop();while(st.length>0){res.push(st[st.length-1].data);st.pop();}returnres;}prev=st[st.length-1];st.pop();}}}returnres;}//Binary tree// 1// / \// 2 3// / \// 4 5// /// 7letroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.left.left.left=newNode(7);letkey=7;letres=ancestors(root,key);console.log(res.join(" "));