[Naive Approach] Recount Leaves for Every Node - O(n^2) Time O(h) Space
The idea is to traverse every node of the binary tree and count the number of leaf nodes in its subtree. For each node, if the subtree contains exactly k leaf nodes, store that node in the result. A postorder traversal is used so that left and right subtrees are processed before the current node.
C++
#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=nullptr;right=nullptr;}};// Function to count leaf nodes in subtreeintcountLeafNodes(Node*root){if(root==nullptr){return0;}// Leaf nodeif(root->left==nullptr&&root->right==nullptr){return1;}returncountLeafNodes(root->left)+countLeafNodes(root->right);}// Postorder traversalvoidpostorder(Node*root,intk,vector<int>&res){if(root==nullptr){return;}postorder(root->left,k,res);postorder(root->right,k,res);intleaves=countLeafNodes(root);// Ignore leaf nodes themselvesif(root->left!=nullptr||root->right!=nullptr){// Store node if subtree has k leavesif(leaves==k){res.push_back(root->data);}}}vector<int>kLeafNodes(Node*root,intk){vector<int>res;postorder(root,k,res);if(res.empty()){return{-1};}returnres;}// Driver Codeintmain(){// Creating treeNode*root=newNode(0);root->left=newNode(1);root->right=newNode(2);root->right->left=newNode(4);root->right->left->left=newNode(5);root->right->left->right=newNode(9);intk=2;vector<int>res=kLeafNodes(root,k);cout<<"[";for(inti=0;i<res.size();i++){cout<<res[i];if(i!=res.size()-1){cout<<", ";}}cout<<"]";return0;}
Java
importjava.util.*;classNode{intdata;Nodeleft;Noderight;Node(intval){data=val;left=null;right=null;}}publicclassGfG{// Function to count leaf nodes in subtreestaticintcountLeafNodes(Noderoot){if(root==null){return0;}// Leaf nodeif(root.left==null&&root.right==null){return1;}returncountLeafNodes(root.left)+countLeafNodes(root.right);}// Postorder traversalstaticvoidpostorder(Noderoot,intk,ArrayList<Integer>res){if(root==null){return;}postorder(root.left,k,res);postorder(root.right,k,res);intleaves=countLeafNodes(root);// Ignore leaf nodes themselvesif(root.left!=null||root.right!=null){// Store node if subtree has k leavesif(leaves==k){res.add(root.data);}}}staticArrayList<Integer>kLeafNodes(Noderoot,intk){ArrayList<Integer>res=newArrayList<>();postorder(root,k,res);if(res.isEmpty()){res.add(-1);}returnres;}// Driver Codepublicstaticvoidmain(String[]args){// Creating treeNoderoot=newNode(0);root.left=newNode(1);root.right=newNode(2);root.right.left=newNode(4);root.right.left.left=newNode(5);root.right.left.right=newNode(9);intk=2;ArrayList<Integer>res=kLeafNodes(root,k);System.out.print("[");for(inti=0;i<res.size();i++){System.out.print(res.get(i));if(i!=res.size()-1){System.out.print(", ");}}System.out.print("]");}}
Python
classNode:def__init__(self,val):self.data=valself.left=Noneself.right=None# Function to count leaf nodes in subtreedefcountLeafNodes(root):ifrootisNone:return0# Leaf nodeifroot.leftisNoneandroot.rightisNone:return1returncountLeafNodes(root.left)+countLeafNodes(root.right)# Postorder traversaldefpostorder(root,k,res):ifrootisNone:returnpostorder(root.left,k,res)postorder(root.right,k,res)leaves=countLeafNodes(root)# Ignore leaf nodes themselvesifroot.leftisnotNoneorroot.rightisnotNone:# Store node if subtree has k leavesifleaves==k:res.append(root.data)defkLeafNodes(root,k):res=[]postorder(root,k,res)ifnotres:return[-1]returnres# Driver Codeif__name__=='__main__':# Creating treeroot=Node(0)root.left=Node(1)root.right=Node(2)root.right.left=Node(4)root.right.left.left=Node(5)root.right.left.right=Node(9)k=2res=kLeafNodes(root,k)print('[',end='')foriinrange(len(res)):print(res[i],end='')ifi!=len(res)-1:print(', ',end='')print(']')
C#
usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intval){data=val;left=null;right=null;}}classGfG{// Function to count leaf nodes in subtreepublicstaticintcountLeafNodes(Noderoot){if(root==null){return0;}// Leaf nodeif(root.left==null&&root.right==null){return1;}returncountLeafNodes(root.left)+countLeafNodes(root.right);}// Postorder traversalpublicstaticvoidpostorder(Noderoot,intk,List<int>res){if(root==null){return;}postorder(root.left,k,res);postorder(root.right,k,res);intleaves=countLeafNodes(root);// Ignore leaf nodes themselvesif(root.left!=null||root.right!=null){// Store node if subtree has k leavesif(leaves==k){res.Add(root.data);}}}publicstaticList<int>kLeafNodes(Noderoot,intk){List<int>res=newList<int>();postorder(root,k,res);if(res.Count==0){res.Add(-1);}returnres;}// Driver CodepublicstaticvoidMain(){// Creating treeNoderoot=newNode(0);root.left=newNode(1);root.right=newNode(2);root.right.left=newNode(4);root.right.left.left=newNode(5);root.right.left.right=newNode(9);intk=2;List<int>res=kLeafNodes(root,k);Console.Write("[");for(inti=0;i<res.Count;i++){Console.Write(res[i]);if(i!=res.Count-1){Console.Write(", ");}}Console.Write("]");}}
JavaScript
classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}// Function to count leaf nodes in subtreefunctioncountLeafNodes(root){if(root===null){return0;}// Leaf nodeif(root.left===null&&root.right===null){return1;}returncountLeafNodes(root.left)+countLeafNodes(root.right);}// Postorder traversalfunctionpostorder(root,k,res){if(root===null){return;}postorder(root.left,k,res);postorder(root.right,k,res);letleaves=countLeafNodes(root);// Ignore leaf nodes themselvesif(root.left!==null||root.right!==null){// Store node if subtree has k leavesif(leaves===k){res.push(root.data);}}}functionkLeafNodes(root,k){letres=[];postorder(root,k,res);if(res.length===0){return[-1];}returnres;}// Driver Code// Creating treeletroot=newNode(0);root.left=newNode(1);root.right=newNode(2);root.right.left=newNode(4);root.right.left.left=newNode(5);root.right.left.right=newNode(9);letk=2;letres=kLeafNodes(root,k);console.log('[');for(leti=0;i<res.length;i++){process.stdout.write(res[i].toString());if(i!==res.length-1){process.stdout.write(', ');}}console.log(']');
Output
[4, 2]
Time Complexity: O(n^2), For every node, we may traverse its entire subtree again. Auxiliary Space: O(h), where h is the height of the tree.
[Expected Approach] Single DFS Leaf Counting - O(n) Time O(h) Space
The idea is to use a single DFS traversal to count the number of leaf nodes in every subtree. For each node, recursively count the leaf nodes in its left and right subtrees and add them to get the total number of leaves below that node. If the total count becomes equal to k, store that node in the result. Since each node is processed only once, this approach avoids repeated subtree traversals.
Working of Approach:
Traverse the binary tree using postorder traversal.
For every node, recursively count the number of leaf nodes in its subtree.
If the current node is not a leaf node and its subtree contains exactly k leaf nodes, store it in the result.
Continue this process for all nodes in the tree.
If no such node exists, return [-1].
C++
#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intval){data=val;left=nullptr;right=nullptr;}};// Returns the number of leaf nodes in the subtree rooted at 'root'intcountLeaves(Node*root,intk,vector<int>&res){if(root==nullptr){return0;}// Leaf nodeif(root->left==nullptr&&root->right==nullptr){return1;}intleftLeaves=countLeaves(root->left,k,res);intrightLeaves=countLeaves(root->right,k,res);inttotalLeaves=leftLeaves+rightLeaves;// Store node if its subtree contains exactly k leavesif(totalLeaves==k){res.push_back(root->data);}returntotalLeaves;}vector<int>kLeafNodes(Node*root,intk){vector<int>res;countLeaves(root,k,res);if(res.empty()){return{-1};}returnres;}// Driver Codeintmain(){// Creating treeNode*root=newNode(0);root->left=newNode(1);root->right=newNode(2);root->right->left=newNode(4);root->right->left->left=newNode(5);root->right->left->right=newNode(9);intk=2;vector<int>res=kLeafNodes(root,k);cout<<"[";for(inti=0;i<res.size();i++){cout<<res[i];if(i!=res.size()-1){cout<<", ";}}cout<<"]";return0;}
Java
importjava.util.ArrayList;classNode{intdata;Nodeleft,right;Node(intval){data=val;left=right=null;}}publicclassGfG{// Returns the number of leaf nodes in the subtree// rooted at 'root'staticintcountLeaves(Noderoot,intk,ArrayList<Integer>res){if(root==null)return0;// Leaf nodeif(root.left==null&&root.right==null)return1;intleftLeaves=countLeaves(root.left,k,res);intrightLeaves=countLeaves(root.right,k,res);inttotalLeaves=leftLeaves+rightLeaves;// Store node if its subtree contains exactly k// leavesif(totalLeaves==k){res.add(root.data);}returntotalLeaves;}staticArrayList<Integer>kLeafNodes(Noderoot,intk){ArrayList<Integer>res=newArrayList<>();countLeaves(root,k,res);if(res.isEmpty()){res.add(-1);}returnres;}// Driver Codepublicstaticvoidmain(String[]args){// Creating treeNoderoot=newNode(0);root.left=newNode(1);root.right=newNode(2);root.right.left=newNode(4);root.right.left.left=newNode(5);root.right.left.right=newNode(9);intk=2;ArrayList<Integer>res=kLeafNodes(root,k);System.out.print("[");for(inti=0;i<res.size();i++){System.out.print(res.get(i));if(i!=res.size()-1){System.out.print(", ");}}System.out.print("]");}}
Python
classNode:def__init__(self,val):self.data=valself.left=Noneself.right=None# Returns the number of leaf nodes in the subtree rooted at 'root'defcountLeaves(root,k,res):ifrootisNone:return0# Leaf nodeifroot.leftisNoneandroot.rightisNone:return1leftLeaves=countLeaves(root.left,k,res)rightLeaves=countLeaves(root.right,k,res)totalLeaves=leftLeaves+rightLeaves# Store node if its subtree contains exactly k leavesiftotalLeaves==k:res.append(root.data)returntotalLeavesdefkLeafNodes(root,k):res=[]countLeaves(root,k,res)ifnotres:return[-1]returnres# Driver Codeif__name__=='__main__':# Creating treeroot=Node(0)root.left=Node(1)root.right=Node(2)root.right.left=Node(4)root.right.left.left=Node(5)root.right.left.right=Node(9)k=2res=kLeafNodes(root,k)print('[',end='')foriinrange(len(res)):print(res[i],end='')ifi!=len(res)-1:print(', ',end='')print(']')
C#
usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intval){data=val;left=right=null;}}classGfG{// Returns the number of leaf nodes in the subtree// rooted at 'root'publicintcountLeaves(Noderoot,intk,List<int>res){if(root==null){return0;}// Leaf nodeif(root.left==null&&root.right==null){return1;}intleftLeaves=countLeaves(root.left,k,res);intrightLeaves=countLeaves(root.right,k,res);inttotalLeaves=leftLeaves+rightLeaves;// Store node if its subtree contains exactly k// leavesif(totalLeaves==k){res.Add(root.data);}returntotalLeaves;}publicList<int>kLeafNodes(Noderoot,intk){List<int>res=newList<int>();countLeaves(root,k,res);if(res.Count==0){returnnewList<int>{-1};}returnres;}// Driver CodestaticvoidMain(string[]args){// Creating treeNoderoot=newNode(0);root.left=newNode(1);root.right=newNode(2);root.right.left=newNode(4);root.right.left.left=newNode(5);root.right.left.right=newNode(9);intk=2;GfGobj=newGfG();List<int>res=obj.kLeafNodes(root,k);Console.Write("[");for(inti=0;i<res.Count;i++){Console.Write(res[i]);if(i!=res.Count-1){Console.Write(", ");}}Console.Write("]");}}
JavaScript
classNode{constructor(val){this.data=val;this.left=null;this.right=null;}}// Returns the number of leaf nodes in the subtree rooted at// 'root'functioncountLeaves(root,k,res){if(root===null)return0;// Leaf nodeif(root.left===null&&root.right===null)return1;letleftLeaves=countLeaves(root.left,k,res);letrightLeaves=countLeaves(root.right,k,res);lettotalLeaves=leftLeaves+rightLeaves;// Store node if its subtree contains exactly k leavesif(totalLeaves===k){res.push(root.data);}returntotalLeaves;}functionkLeafNodes(root,k){letres=[];countLeaves(root,k,res);if(res.length===0){res.push(-1);}returnres;}// Driver Code// Creating treeletroot=newNode(0);root.left=newNode(1);root.right=newNode(2);root.right.left=newNode(4);root.right.left.left=newNode(5);root.right.left.right=newNode(9);letk=2;letres=kLeafNodes(root,k);console.log("[");for(leti=0;i<res.length;i++){process.stdout.write(res[i].toString());if(i!==res.length-1){process.stdout.write(", ");}}console.log("]");
Output
[4, 2]
Time Complexity: O(n), Every node is visited only once. Auxiliary Space: O(h), where h is the height of the tree.