[Expected Approach - 1] Using Inorder and Preorder - O(nlogn) Time and O(n) Space
The idea is to find Inorder by sorting the input preorder traversal, then traverse the tree in preorder fashion (using both inorder and preorder traversals) and while traversing store the leaf nodes.
How to traverse in preorder fashion using two arrays representing inorder and preorder traversals?
We iterate the preorder array and for each element find that element in the inorder array. For searching, we can use binary search, since inorder traversal of the binary search tree is always sorted. Now, for each element of preorder array, in binary search, we set the range [l, r].
And when l == r, the leaf node is found. So, initially, l = 0 and l = n - 1 for first element (i.e root) of preorder array. Now, to search for the element on the left subtree of the root, set l = 0 and r= index of root - 1. Also, for all element of right subtree set l = index of root + 1 and r = n -1. Recursively, follow this, until l == r.
C++
// C++ program to print leaf node from preorder of// binary search tree using inorder + preorder#include<bits/stdc++.h>usingnamespacestd;intbinarySearch(vector<int>&inorder,intl,intr,intd){intmid=(l+r)>>1;if(inorder[mid]==d)returnmid;elseif(inorder[mid]>d)returnbinarySearch(inorder,l,mid-1,d);elsereturnbinarySearch(inorder,mid+1,r,d);}// Function to find Leaf Nodes by doing preorder// traversal of tree using preorder and inorder vectors.voidleafNodesRec(vector<int>&preorder,vector<int>&inorder,intl,intr,int&ind,vector<int>&leaves){// If l == r, therefore no right or left subtree.// So, it must be leaf Node, store it.if(l==r){leaves.push_back(inorder[l]);ind++;return;}// If array is out of bound, return.if(l<0||l>r||r>=inorder.size())return;// Finding the index of preorder element// in inorder vector using binary search.intloc=binarySearch(inorder,l,r,preorder[ind]);ind++;// Finding on the left subtree.leafNodesRec(preorder,inorder,l,loc-1,ind,leaves);// Finding on the right subtree.leafNodesRec(preorder,inorder,loc+1,r,ind,leaves);}// Finds leaf nodes from given preorder traversal.vector<int>leafNodes(vector<int>&preorder){intn=preorder.size();vector<int>inorder(n);vector<int>leaves;// Copy the preorder into another vector.for(inti=0;i<n;i++)inorder[i]=preorder[i];// Finding the inorder by sorting the vector.sort(inorder.begin(),inorder.end());// Point to the index in preorder.intind=0;// Find the Leaf Nodes.leafNodesRec(preorder,inorder,0,n-1,ind,leaves);returnleaves;}intmain(){vector<int>preorder={4,2,1,3,6,5};vector<int>result=leafNodes(preorder);for(intval:result){cout<<val<<" ";}return0;}
# Python program to print leaf nodes from preorder of# binary search tree using inorder + preorderdefbinarySearch(inorder,l,r,d):mid=(l+r)//2ifinorder[mid]==d:returnmidelifinorder[mid]>d:returnbinarySearch(inorder,l,mid-1,d)else:returnbinarySearch(inorder,mid+1,r,d)# Function to find Leaf Nodes by doing preorder# traversal of tree using preorder and inorder lists.defleafNodesRec(preorder,inorder,l,r,ind,leaves):# If l == r, therefore no right or left subtree.# So, it must be leaf Node, store it.ifl==r:leaves.append(inorder[l])ind[0]+=1return# If array is out of bounds, return.ifl<0orl>rorr>=len(inorder):return# Finding the index of preorder element in # inorder list using binary search.loc=binarySearch(inorder,l,r,preorder[ind[0]])ind[0]+=1# Finding on the left subtree.leafNodesRec(preorder,inorder,l,loc-1,ind,leaves)# Finding on the right subtree.leafNodesRec(preorder,inorder,loc+1,r,ind,leaves)# Finds leaf nodes from given preorder traversal.defleafNodes(preorder):n=len(preorder)inorder=sorted(preorder)leaves=[]# Point to the index in preorder.ind=[0]# Find the Leaf Nodes.leafNodesRec(preorder,inorder,0,n-1,ind,leaves)returnleavesif__name__=="__main__":preorder=[4,2,1,3,6,5]result=leafNodes(preorder)forvalinresult:print(val,end=" ")
C#
usingSystem;usingSystem.Collections.Generic;classGfG{staticintBinarySearch(List<int>inorder,intl,intr,intd){intmid=(l+r)/2;if(inorder[mid]==d)returnmid;elseif(inorder[mid]>d)returnBinarySearch(inorder,l,mid-1,d);elsereturnBinarySearch(inorder,mid+1,r,d);}staticvoidLeafNodesRec(int[]preorder,List<int>inorder,intl,intr,int[]ind,List<int>leaves){if(l==r){leaves.Add(inorder[l]);ind[0]++;return;}if(l<0||l>r||r>=inorder.Count)return;intloc=BinarySearch(inorder,l,r,preorder[ind[0]]);ind[0]++;LeafNodesRec(preorder,inorder,l,loc-1,ind,leaves);LeafNodesRec(preorder,inorder,loc+1,r,ind,leaves);}staticList<int>leafNodes(int[]preorder){intn=preorder.Length;// Convert array to List and sort for inorderList<int>inorder=newList<int>(preorder);inorder.Sort();List<int>leaves=newList<int>();int[]ind=newint[1]{0};LeafNodesRec(preorder,inorder,0,n-1,ind,leaves);returnleaves;}staticvoidMain(){int[]preorder={4,2,1,3,6,5};List<int>result=leafNodes(preorder);foreach(intvalinresult){Console.Write(val+" ");}}}
JavaScript
// JavaScript program to print leaf nodes from preorder of// binary search tree using inorder + preorderfunctionbinarySearch(inorder,l,r,d){constmid=Math.floor((l+r)/2);if(inorder[mid]===d){returnmid;}elseif(inorder[mid]>d){returnbinarySearch(inorder,l,mid-1,d);}else{returnbinarySearch(inorder,mid+1,r,d);}}// Function to find Leaf Nodes by doing preorder// traversal of tree using preorder and inorder arrays.functionleafNodesRec(preorder,inorder,l,r,ind,leaves){// If l == r, therefore no right or left subtree.// So, it must be a leaf Node, store it.if(l===r){leaves.push(inorder[l]);ind[0]++;return;}// If array is out of bounds, return.if(l<0||l>r||r>=inorder.length){return;}// Finding the index of preorder element// in inorder array using binary search.constloc=binarySearch(inorder,l,r,preorder[ind[0]]);ind[0]++;// Finding on the left subtree.leafNodesRec(preorder,inorder,l,loc-1,ind,leaves);// Finding on the right subtree.leafNodesRec(preorder,inorder,loc+1,r,ind,leaves);}// Finds leaf nodes from given preorder traversal.functionleafNodes(preorder){constn=preorder.length;constinorder=[...preorder];inorder.sort((a,b)=>a-b);constleaves=[];// Point to the index in preorder.constind=[0];// Find the Leaf Nodes.leafNodesRec(preorder,inorder,0,n-1,ind,leaves);returnleaves;}// Driver Codeconstpreorder=[4,2,1,3,6,5];constresult=leafNodes(preorder);console.log(result.join(' '));
Output
1 3 5
[Expected Approach - 2] Using Stack - O(n) Time and O(n) Space
The idea is to use the property of the Binary Search Tree and stack. Traverse the array using two pointer i and j to the array, initially i = 0 and j = 1. Whenever a[i] > a[j], we can say a[j] is left part of a[i], since preorder traversal follows Node -> Left -> Right. So, we push a[i] into the stack.
For those points violating the rule, we start to pop element from the stack till a[i] > top element of the stack and break when it doesn't and print the corresponding jth value.
How does this algorithm work? Preorder traversal traverse in the order: Node, Left, Right. And we know the left node of any node in BST is always less than the node. So preorder traversal will first traverse from root to leftmost node. Therefore, preorder will be in decreasing order first. Now, after decreasing order, there may be a node that is greater or which breaks the decreasing order. So, there can be a case like this :
In case 1, 20 is a leaf node whereas in case 2, 20 is not the leaf node. So, our problem is how to identify if we have to print 20 as a leaf node or not? This is solved using stack. While running above algorithm on case 1 and case 2, when i = 2 and j = 3, state of a stack will be the same in both the case:
So, node 65 will pop 20 and 50 from the stack. This is because 65 is the right child of a node which is before 20. This information we store using the found variable. So, 20 is a leaf node. While in case 2, 40 will not able to pop any element from the stack. Because 40 is the right node of a node which is after 20. So, 20 is not a leaf node. Note: In the algorithm, we will not be able to check the condition of the leaf node of the rightmost node or rightmost element of the preorder. So, simply print the rightmost node because we know this will always be a leaf node in preorder traversal.
C++
// C++ program to print leaf nodes from the preorder // traversal of a Binary Search Tree using a stack#include<iostream>#include<stack>#include<vector>usingnamespacestd;// Function to find leaf nodes from the // preorder traversalvector<int>leafNodes(vector<int>&preorder){stack<int>s;vector<int>leaves;intn=preorder.size();// Iterate through the preorder vectorfor(inti=0,j=1;j<n;i++,j++){boolfound=false;// Push current node if it's greater than // the next nodeif(preorder[i]>preorder[j]){s.push(preorder[i]);}else{// Pop elements from stack until current node is // less than or equal to top of stackwhile(!s.empty()){if(preorder[j]>s.top()){s.pop();found=true;}else{break;}}}// If a leaf node is found, add it // to the leaves vectorif(found){leaves.push_back(preorder[i]);}}// Since the rightmost element // is always a leaf nodeleaves.push_back(preorder[n-1]);returnleaves;}intmain(){vector<int>preorder={4,2,1,3,6,5};vector<int>result=leafNodes(preorder);for(intval:result){cout<<val<<" ";}return0;}
Java
importjava.util.ArrayList;importjava.util.Stack;importjava.util.Arrays;classGfG{// Function to find leaf nodes from the // preorder traversalstaticArrayList<Integer>leafNodes(int[]preorder){Stack<Integer>s=newStack<>();ArrayList<Integer>leaves=newArrayList<>();intn=preorder.length;// Iterate through the preorder arrayfor(inti=0,j=1;j<n;i++,j++){booleanfound=false;// Push current node if it's greater than the nextif(preorder[i]>preorder[j]){s.push(preorder[i]);}else{// Pop elements from stack until the next value is// less than or equal to topwhile(!s.isEmpty()){if(preorder[j]>s.peek()){s.pop();found=true;}else{break;}}}// If a leaf node is found, add it to resultif(found){leaves.add(preorder[i]);}}// Add the last element, it's always a leaf in BST preorderleaves.add(preorder[n-1]);returnleaves;}publicstaticvoidmain(String[]args){int[]preorder={4,2,1,3,6,5};ArrayList<Integer>result=leafNodes(preorder);for(intval:result){System.out.print(val+" ");}}}
Python
# Python program to print leaf nodes from the preorder # traversal of a Binary Search Tree using a stackdefleafNodes(preorder):s=[]leaves=[]n=len(preorder)# Iterate through the preorder listforiinrange(n-1):found=False# Push current node if it's greater# than the next nodeifpreorder[i]>preorder[i+1]:s.append(preorder[i])else:# Pop elements from stack until current node is # less than or equal to top of stackwhilesandpreorder[i+1]>s[-1]:s.pop()found=True# If a leaf node is found, add it to the# leaves listiffound:leaves.append(preorder[i])# Since the rightmost element is always# a leaf nodeleaves.append(preorder[-1])returnleavesif__name__=="__main__":preorder=[4,2,1,3,6,5]result=leafNodes(preorder)print(" ".join(map(str,result)))
C#
usingSystem;usingSystem.Collections.Generic;classGfG{// Function to find leaf nodes from the preorder traversalstaticList<int>leafNodes(int[]preorder){Stack<int>s=newStack<int>();List<int>leaves=newList<int>();intn=preorder.Length;// Iterate through the preorder arrayfor(inti=0,j=1;j<n;i++,j++){boolfound=false;// Push current node if it's greater than the next nodeif(preorder[i]>preorder[j]){s.Push(preorder[i]);}else{// Pop elements until next is not greater than topwhile(s.Count>0){if(preorder[j]>s.Peek()){s.Pop();found=true;}else{break;}}}if(found){leaves.Add(preorder[i]);}}// Last node is always a leafleaves.Add(preorder[n-1]);returnleaves;}staticvoidMain(string[]args){int[]preorder={4,2,1,3,6,5};List<int>result=leafNodes(preorder);foreach(intvalinresult){Console.Write(val+" ");}}}
JavaScript
// JavaScript program to print leaf nodes from the preorder // traversal of a Binary Search Tree using a stackfunctionleafNodes(preorder){lets=[];letleaves=[];letn=preorder.length;// Iterate through the preorder listfor(leti=0,j=1;j<n;i++,j++){letfound=false;// Push current node if it's greater // than the next nodeif(preorder[i]>preorder[j]){s.push(preorder[i]);}else{// Pop elements from stack until current node is // less than or equal to top of stackwhile(s.length>0&&preorder[j]>s[s.length-1]){s.pop();found=true;}}// If a leaf node is found, add it to the leaves arrayif(found){leaves.push(preorder[i]);}}// Since the rightmost element is always a leaf nodeleaves.push(preorder[n-1]);returnleaves;}// Driver Codeletpreorder=[4,2,1,3,6,5];letresult=leafNodes(preorder);console.log(result.join(' '));