[Expected Approach - 1] Using Parent HashMap - O(n) Time and O(n) Space
The idea is to use a preorder traversal technique using a stack, and maintainhashmap to keep track of each node's parent, When we reach at leaf node, print path from root to that lead node using parent map.
Follow the steps below to solve the problem:
Push the root node onto the stack and Store the root's parent as null in the parent map.
While the stack is not empty, pop the top node
If the node is a leaf node then Trace the path from the leaf node to the root using the parent map and print the path.
If the node has a right child, push it onto the stack and store its parent in the map.
If the node has a left child, push it onto the stack and store its parent in the map.
Below is the implementation of this idea.
C++
// C++ program to Print root to leaf path without// using recursion#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intx){data=x;left=right=nullptr;}};// Function to print root to leaf path for a leaf// using parent nodes stored in mapvoidprintTopToBottomPath(Node*curr,unordered_map<Node*,Node*>&parent){stack<Node*>stk;// start from leaf node and keep on pushing// nodes into stack till root node is reachedwhile(curr){stk.push(curr);curr=parent[curr];}// Start popping nodes from stack and print themwhile(!stk.empty()){curr=stk.top();stk.pop();cout<<curr->data<<" ";}cout<<endl;}// An iterative function to do preorder traversal// of binary tree and print root to leaf path// without using recursion voidprintRootToLeaf(Node*root){if(root==nullptr)return;// Create an empty stack and push root// to itstack<Node*>nodeStack;nodeStack.push(root);// Create a map to store parent pointers // of binary tree nodesunordered_map<Node*,Node*>parent;// parent of root is NULLparent[root]=nullptr;while(!nodeStack.empty()){// Pop the top item from stackNode*current=nodeStack.top();nodeStack.pop();// If leaf node encountered, print Top To// Bottom pathif(!(current->left)&&!(current->right)){printTopToBottomPath(current,parent);}// Push right & left children of the popped node// to stack. Also set their parent pointer in// the map// Note that right child is pushed first so that// left is processed first if(current->right){parent[current->right]=current;nodeStack.push(current->right);}if(current->left){parent[current->left]=current;nodeStack.push(current->left);}}}intmain(){// Constructed binary tree is// 10// / \ // 8 2// / \ /// 3 5 2 Node*root=newNode(10);root->left=newNode(8);root->right=newNode(2);root->left->left=newNode(3);root->left->right=newNode(5);root->right->left=newNode(2);printRootToLeaf(root);return0;}
Java
// Java program to Print root to leaf path without// using recursionimportjava.util.*;classNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classGfG{// Function to print root to leaf path for a leaf// using parent nodes stored in mapstaticvoidprintTopToBottomPath(Nodecurr,Map<Node,Node>parent){Stack<Node>stk=newStack<>();// start from leaf node and keep on pushing// nodes into stack till root node is reachedwhile(curr!=null){stk.push(curr);curr=parent.get(curr);}// Start popping nodes from stack and print themwhile(!stk.isEmpty()){curr=stk.pop();System.out.print(curr.data+" ");}System.out.println();}// An iterative function to do preorder traversal// of binary tree and print root to leaf path// without using recursionstaticvoidprintRootToLeaf(Noderoot){if(root==null)return;// Create an empty stack and push root to itStack<Node>nodeStack=newStack<>();nodeStack.push(root);// Create a map to store parent pointers of binary// tree nodesMap<Node,Node>parent=newHashMap<>();// parent of root is NULLparent.put(root,null);while(!nodeStack.isEmpty()){// Pop the top item from stackNodecurrent=nodeStack.pop();// If leaf node encountered, print Top To// Bottom pathif(current.left==null&¤t.right==null){printTopToBottomPath(current,parent);}// Push right & left children of the popped node// to stack. Also set their parent pointer in// the map// Note that right child is pushed first so that// left is processed firstif(current.right!=null){parent.put(current.right,current);nodeStack.push(current.right);}if(current.left!=null){parent.put(current.left,current);nodeStack.push(current.left);}}}publicstaticvoidmain(String[]args){// Constructed binary tree is// 10// / \// 8 2// / \ /// 3 5 2Noderoot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);printRootToLeaf(root);}}
Python
# Python program to Print root to leaf path without# using recursionclassNode:def__init__(self,data):self.data=dataself.left=Noneself.right=None# Function to print root to leaf path for a leaf# using parent nodes stored in mapdefprintTopToBottomPath(curr,parent):stk=[]# start from leaf node and keep on pushing# nodes into stack till root node is reachedwhilecurr:stk.append(curr)curr=parent[curr]# Start popping nodes from stack and print themwhilestk:curr=stk.pop()print(curr.data,end=" ")print()# An iterative function to do preorder traversal# of binary tree and print root to leaf path# without using recursiondefprintRootToLeaf(root):ifrootisNone:return# Create an empty stack and push root to itnodeStack=[]nodeStack.append(root)# Create a dictionary to store parent pointers# of binary tree nodesparent={}# parent of root is Noneparent[root]=NonewhilenodeStack:# Pop the top item from stackcurrent=nodeStack.pop()# If leaf node encountered, print Top To# Bottom pathifnotcurrent.leftandnotcurrent.right:printTopToBottomPath(current,parent)# Push right & left children of the popped node# to stack. Also set their parent pointer in# the dictionary# Note that right child is pushed first so that# left is processed firstifcurrent.right:parent[current.right]=currentnodeStack.append(current.right)ifcurrent.left:parent[current.left]=currentnodeStack.append(current.left)# Constructed binary tree is# 10# / \# 8 2# / \ /# 3 5 2root=Node(10)root.left=Node(8)root.right=Node(2)root.left.left=Node(3)root.left.right=Node(5)root.right.left=Node(2)printRootToLeaf(root)
C#
// C# program to Print root to leaf path without// using recursionusingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}classGfG{// Function to print root to leaf path for a leaf// using parent nodes stored in mapstaticvoidprintTopToBottomPath(Nodecurr,Dictionary<Node,Node>parent){Stack<Node>stk=newStack<Node>();// start from leaf node and keep on pushing// nodes into stack till root node is reachedwhile(curr!=null){stk.Push(curr);curr=parent[curr];}// Start popping nodes from stack and print themwhile(stk.Count>0){curr=stk.Pop();Console.Write(curr.data+" ");}Console.WriteLine();}// An iterative function to do preorder traversal// of binary tree and print root to leaf path// without using recursionstaticvoidprintRootToLeaf(Noderoot){if(root==null)return;// Create an empty stack and push root to itStack<Node>nodeStack=newStack<Node>();nodeStack.Push(root);// Create a map to store parent pointers of binary// tree nodesDictionary<Node,Node>parent=newDictionary<Node,Node>();// parent of root is NULLparent[root]=null;while(nodeStack.Count>0){// Pop the top item from stackNodecurrent=nodeStack.Pop();// If leaf node encountered, print Top To// Bottom pathif(current.left==null&¤t.right==null){printTopToBottomPath(current,parent);}// Push right & left children of the popped node// to stack. Also set their parent pointer in// the map// Note that right child is pushed first so that// left is processed firstif(current.right!=null){parent[current.right]=current;nodeStack.Push(current.right);}if(current.left!=null){parent[current.left]=current;nodeStack.Push(current.left);}}}staticvoidMain(){// Constructed binary tree is// 10// / \// 8 2// / \ /// 3 5 2Noderoot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);printRootToLeaf(root);}}
JavaScript
// Javascript program to Print root to leaf path without// using recursionclassNode{constructor(data){this.data=data;this.left=null;this.right=null;}}// Function to print root to leaf path for a leaf// using parent nodes stored in mapfunctionprintTopToBottomPath(curr,parent){letstk=[];// start from leaf node and keep on pushing// nodes into stack till root node is reachedwhile(curr){stk.push(curr);curr=parent.get(curr);}// Start popping nodes from stack and print themwhile(stk.length>0){curr=stk.pop();process.stdout.write(curr.data+" ");}console.log();}// An iterative function to do preorder traversal// of binary tree and print root to leaf path// without using recursionfunctionprintRootToLeaf(root){if(root===null)return;// Create an empty stack and push root to itletnodeStack=[];nodeStack.push(root);// Create a map to store parent pointers of binary// tree nodesletparent=newMap();// parent of root is NULLparent.set(root,null);while(nodeStack.length>0){// Pop the top item from stackletcurrent=nodeStack.pop();// If leaf node encountered, print Top To// Bottom pathif(!current.left&&!current.right){printTopToBottomPath(current,parent);}// Push right & left children of the popped node// to stack. Also set their parent pointer in// the map// Note that right child is pushed first so that// left is processed firstif(current.right){parent.set(current.right,current);nodeStack.push(current.right);}if(current.left){parent.set(current.left,current);nodeStack.push(current.left);}}}// Constructed binary tree is// 10// / \// 8 2// / \ /// 3 5 2letroot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);printRootToLeaf(root);
Output
10 8 3
10 8 5
10 2 2
Note : We can optimize this approach. We do not need to maintain parent map. Below there is another approach by we can print all path from root to leaf without using parent array.
[Expected Approach - 2] Using Stack - O(n) Time and O(n) Space
The idea is to use stack to store pairs of nodes and their respective paths from the root, starting with the root node and its value, traverse iteratively by processing each node by popping it from the stack. if the node is a leaf, its path is added to the result. else if the node has children, the right and left children are pushed onto the stack along with theirupdated paths.
Follow the steps below to solve the problem:
Initialize stack, that stores pairs of nodes and the path from the root to that node.
Push the root node and its path (starting with just the root’s value) onto the stack.
While the stack isn't empty, pop a pair of node and its path from the stack.
If the current node is a leaf, add its path to the result.
If the current node has a right child, push the right child and its updated path onto the stack.
If the current node has a left child, push the left child and its updated path onto the stack.
return result which represents all the paths from root-to-leaf.
Below is the implementation of the above approach:
C++
// C++ code of print all paths from root node // to leaf node using stack#include<iostream>#include<vector>#include<stack>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};// Function to get all paths from root // to leaf nodes using a stackvector<vector<int>>Paths(Node*root){vector<vector<int>>result;if(!root)returnresult;// Stack to store pairs of nodes and the // path from the root to that nodestack<pair<Node*,vector<int>>>stk;stk.push({root,{root->data}});while(!stk.empty()){// Get the current node and its // associated path from the stackautocurr=stk.top();stk.pop();Node*currNode=curr.first;vector<int>path=curr.second;// If the current node is a leaf node,// add its path to the resultif(!currNode->left&&!currNode->right){result.push_back(path);}// If the current node has a right child, // push it to the stack with its pathif(currNode->right){vector<int>rightPath=path;rightPath.push_back(currNode->right->data);stk.push({currNode->right,rightPath});}// If the current node has a left child, // push it to the stack with its pathif(currNode->left){vector<int>leftPath=path;leftPath.push_back(currNode->left->data);stk.push({currNode->left,leftPath});}}returnresult;}intmain(){// Constructed binary tree is // 10 // / \ // 8 2 // / \ /// 3 5 2 Node*root=newNode(10);root->left=newNode(8);root->right=newNode(2);root->left->left=newNode(3);root->left->right=newNode(5);root->right->left=newNode(2);vector<vector<int>>paths=Paths(root);for(constauto&path:paths){for(intnodeValue:path){cout<<nodeValue<<" ";}cout<<endl;}return0;}
Java
// Java code of print all paths from root node // to leaf node using stackimportjava.util.*;classNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classPair{Nodenode;List<Integer>path;publicPair(Nodenode,List<Integer>path){this.node=node;this.path=path;}}classGfG{// Function to get all paths from root // to leaf nodes using a stackstaticList<List<Integer>>Paths(Noderoot){List<List<Integer>>result=newArrayList<>();if(root==null)returnresult;// Stack to store pairs of nodes and the // path from the root to that nodeStack<Pair>stk=newStack<>();// Create an ArrayList with the root node's dataList<Integer>rootPath=newArrayList<>();rootPath.add(root.data);stk.push(newPair(root,rootPath));while(!stk.isEmpty()){// Get the current node and its // associated path from the stackPaircurr=stk.pop();NodecurrNode=curr.node;List<Integer>path=curr.path;// If the current node is a leaf node,// add its path to the resultif(currNode.left==null&&currNode.right==null){result.add(path);}// If the current node has a right child, // push it to the stack with its pathif(currNode.right!=null){List<Integer>rightPath=newArrayList<>(path);rightPath.add(currNode.right.data);stk.push(newPair(currNode.right,rightPath));}// If the current node has a left child, // push it to the stack with its pathif(currNode.left!=null){List<Integer>leftPath=newArrayList<>(path);leftPath.add(currNode.left.data);stk.push(newPair(currNode.left,leftPath));}}returnresult;}publicstaticvoidmain(String[]args){// Constructed binary tree is // 10 // / \ // 8 2 // / \ /// 3 5 2 Noderoot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);List<List<Integer>>paths=Paths(root);for(List<Integer>path:paths){for(intnodeValue:path){System.out.print(nodeValue+" ");}System.out.println();}}}
Python
# Python code to print all paths from # root node to leaf node using stack.classNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Function to get all paths from root # to leaf nodes using a stackdefPaths(root):result=[]ifnotroot:returnresult# Stack to store pairs of nodes and the # path from the root to that nodestk=[(root,[root.data])]whilestk:# Get the current node and its # associated path from the stackcurrNode,path=stk.pop()# If the current node is a leaf node,# add its path to the resultifnotcurrNode.leftandnotcurrNode.right:result.append(path)# If the current node has a right child, # push it to the stack with its pathifcurrNode.right:rightPath=path+[currNode.right.data]stk.append((currNode.right,rightPath))# If the current node has a left child, # push it to the stack with its pathifcurrNode.left:leftPath=path+[currNode.left.data]stk.append((currNode.left,leftPath))returnresultif__name__=="__main__":# Constructed binary tree is # 10 # / \ # 8 2 # / \ /# 3 5 2 root=Node(10)root.left=Node(8)root.right=Node(2)root.left.left=Node(3)root.left.right=Node(5)root.right.left=Node(2)paths=Paths(root)forpathinpaths:print(" ".join(map(str,path)))
C#
// C# code to print all paths from root // node to leaf node using stack.usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}classGfG{// Function to get all paths from root // to leaf nodes using a stackstaticList<List<int>>Paths(Noderoot){List<List<int>>result=newList<List<int>>();if(root==null)returnresult;// Stack to store pairs of nodes and the // path from the root to that nodeStack<Tuple<Node,List<int>>>stk=newStack<Tuple<Node,List<int>>>();stk.Push(Tuple.Create(root,newList<int>{root.data}));while(stk.Count>0){// Get the current node and its // associated path from the stackvarcurr=stk.Pop();NodecurrNode=curr.Item1;List<int>path=curr.Item2;// If the current node is a leaf node,// add its path to the resultif(currNode.left==null&&currNode.right==null){result.Add(path);}// If the current node has a right child, // push it to the stack with its pathif(currNode.right!=null){List<int>rightPath=newList<int>(path);rightPath.Add(currNode.right.data);stk.Push(Tuple.Create(currNode.right,rightPath));}// If the current node has a left child, // push it to the stack with its pathif(currNode.left!=null){List<int>leftPath=newList<int>(path);leftPath.Add(currNode.left.data);stk.Push(Tuple.Create(currNode.left,leftPath));}}returnresult;}staticvoidMain(){// Constructed binary tree is // 10 // / \ // 8 2 // / \ /// 3 5 2 Noderoot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);List<List<int>>paths=Paths(root);foreach(varpathinpaths){Console.WriteLine(string.Join(" ",path));}}}
JavaScript
// JavaScript code to print all paths from // root node to leaf node using stack.classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Function to get all paths from root // to leaf nodes using a stackfunctionPaths(root){constresult=[];if(!root)returnresult;// Stack to store pairs of nodes and the // path from the root to that nodeconststk=[[root,[root.data]]];while(stk.length>0){// Get the current node and its // associated path from the stackconst[currNode,path]=stk.pop();// If the current node is a leaf node,// add its path to the resultif(!currNode.left&&!currNode.right){result.push(path);}// If the current node has a right child, // push it to the stack with its pathif(currNode.right){constrightPath=[...path,currNode.right.data];stk.push([currNode.right,rightPath]);}// If the current node has a left child, // push it to the stack with its pathif(currNode.left){constleftPath=[...path,currNode.left.data];stk.push([currNode.left,leftPath]);}}returnresult;}// Constructed binary tree is // 10 // / \ // 8 2 // / \ /// 3 5 2 constroot=newNode(10);root.left=newNode(8);root.right=newNode(2);root.left.left=newNode(3);root.left.right=newNode(5);root.right.left=newNode(2);constallPaths=Paths(root);allPaths.forEach(path=>{console.log(path.join(' '));});