Count root to leaf paths having exactly K distinct nodes in a Binary Tree
Last Updated :
22 Jun, 2021
Given a Binary Tree consisting of N nodes rooted at 1, an integer K and an array arr[] consisting of values assigned to each node, the task is to count the number of root to leaf paths having exactly K distinct nodes in the given Binary Tree.
Examples:
Input: N = 3, Edges[][] = {{1, 2}, {1, 3}}, arr[] = {3, 3, 2}, K = 2, Below is the given Tree:
Output: 1
Explanation:
There exists only 1 distinct path i.e., Path 1 -> 3 contains 2 distinct nodes.
Hence, the answer is 1.
Input: N = 7, Edges[][] = {{1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {3, 7}}, arr[] = {2, 2, 2, 2, 3, 5, 2}, K = 1, Below is the given Tree:
Output: 2
Explanation:
There exists only 2 distinct paths containing 1 distinct node:
1) Paths 1 -> 2 -> 4,
2) Paths 1 -> 3 -> 7
Hence, the answer is 2.
Naive Approach: The simplest approach is to generate all possible paths from the root to the leaf nodes and for each path, check if it contains K distinct nodes or not. Finally, print the count of such paths.
Time Complexity: O(N * H2), where H denotes the height of the tree.
Auxiliary Space: O(N);
Efficient Approach: The idea is to use Preorder Traversal and a Map to count the distinct node in the path from the root to the current node. Follow the below steps to solve the problem:
- Initialize a variable distinct_nodes as 0 to store the count of the distinct node from the root to the current node and ans as 0 to store the total distinct root to leaf paths having K distinct node.
- Perform Preorder Traversal in the given binary tree and store the count of the distinct node from root to the current node in the map M.
- Whenever a node occurs for the first time on a path, increase the count of distinct nodes by 1.
- If the count of distinct nodes on a path becomes greater than K return to the parent node of the current node.
- Otherwise, continue to visit the children of the current node incrementing the frequency of the current node value by 1.
- In the above step, increment ans by 1 if the count of distinct nodes on that root to leaf path is exactly equal to K.
- After the above steps print the value of ans as the resultant count.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int key;
Node *left, *right;
};
Node* newNode( int key)
{
Node* temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return temp;
}
void findkDistinctNodePaths(
Node* root, unordered_map< int , int > freq,
int distinct_nodes, int k, int & ans)
{
if (root == NULL)
return ;
if (freq[root->key] == 0)
distinct_nodes++;
if (distinct_nodes > k)
return ;
freq[root->key]++;
findkDistinctNodePaths(root->left,
freq,
distinct_nodes,
k, ans);
findkDistinctNodePaths(root->right,
freq,
distinct_nodes,
k, ans);
if (root->left == NULL
&& root->right == NULL) {
if (distinct_nodes == k)
ans++;
}
}
void printkDistinctNodePaths(Node* root,
int k)
{
unordered_map< int , int > freq;
int distinct_nodes = 0;
int ans = 0;
findkDistinctNodePaths(root, freq,
distinct_nodes,
k, ans);
cout << ans;
}
int main()
{
Node* root = newNode(2);
root->left = newNode(1);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(2);
root->right->left = newNode(-5);
root->right->right = newNode(3);
int K = 2;
printkDistinctNodePaths(root, K);
return 0;
}
|
Java
import java.util.*;
class GFG{
static class Node
{
int key;
Node left, right;
};
static int ans;
static Node newNode( int key)
{
Node temp = new Node();
temp.key = key;
temp.left = temp.right = null ;
return temp;
}
static void findkDistinctNodePaths(Node root,
HashMap<Integer,
Integer> freq,
int distinct_nodes,
int k)
{
if (root == null )
return ;
if (!freq.containsKey(root.key))
distinct_nodes++;
if (distinct_nodes > k)
return ;
if (freq.containsKey(root.key))
{
freq.put(root.key,
freq.get(root.key) + 1 );
}
else
{
freq.put(root.key, 1 );
}
findkDistinctNodePaths(root.left, freq,
distinct_nodes, k);
findkDistinctNodePaths(root.right, freq,
distinct_nodes, k);
if (root.left == null &&
root.right == null )
{
if (distinct_nodes == k)
ans++;
}
}
static void printkDistinctNodePaths(Node root,
int k)
{
HashMap<Integer,
Integer> freq = new HashMap<>();
int distinct_nodes = 0 ;
ans = 0 ;
findkDistinctNodePaths(root, freq,
distinct_nodes, k);
System.out.print(ans);
}
public static void main(String[] args)
{
Node root = newNode( 2 );
root.left = newNode( 1 );
root.right = newNode( 3 );
root.left.left = newNode( 4 );
root.left.right = newNode( 2 );
root.right.left = newNode(- 5 );
root.right.right = newNode( 3 );
int K = 2 ;
printkDistinctNodePaths(root, K);
}
}
|
Python3
class newNode:
def __init__( self , key):
self .key = key
self .left = None
self .right = None
ans = 0
def findkDistinctNodePaths(root, freq,
distinct_nodes, k):
global ans
if (root = = None ):
return
if (root.key not in freq):
distinct_nodes + = 1
if (distinct_nodes > k):
return
if (root.key in freq):
freq[root.key] + = 1
else :
freq[root.key] = freq.get(root.key, 0 ) + 1
findkDistinctNodePaths(root.left, freq,
distinct_nodes, k)
findkDistinctNodePaths(root.right, freq,
distinct_nodes, k)
if (root.left = = None and
root.right = = None ):
if (distinct_nodes = = k):
ans + = 1
def printkDistinctNodePaths(root, k):
global ans
freq = {}
distinct_nodes = 0
findkDistinctNodePaths(root, freq,
distinct_nodes, k)
print (ans)
if __name__ = = '__main__' :
root = newNode( 2 )
root.left = newNode( 1 )
root.right = newNode( 3 )
root.left.left = newNode( 4 )
root.left.right = newNode( 2 )
root.right.left = newNode( - 5 )
root.right.right = newNode( 3 )
K = 2
printkDistinctNodePaths(root, K)
|
C#
using System;
using System.Collections.Generic;
class GFG{
public class Node
{
public int key;
public Node left, right;
};
static int ans;
static Node newNode( int key)
{
Node temp = new Node();
temp.key = key;
temp.left = temp.right = null ;
return temp;
}
static void findkDistinctNodePaths(Node root,
Dictionary< int , int > freq,
int distinct_nodes,
int k)
{
if (root == null )
return ;
if (!freq.ContainsKey(root.key))
distinct_nodes++;
if (distinct_nodes > k)
return ;
if (freq.ContainsKey(root.key))
{
freq[root.key] = freq[root.key] + 1;
}
else
{
freq.Add(root.key, 1);
}
findkDistinctNodePaths(root.left, freq,
distinct_nodes, k);
findkDistinctNodePaths(root.right, freq,
distinct_nodes, k);
if (root.left == null &&
root.right == null )
{
if (distinct_nodes == k)
ans++;
}
}
static void printkDistinctNodePaths(Node root,
int k)
{
Dictionary< int ,
int > freq = new Dictionary< int ,
int >();
int distinct_nodes = 0;
ans = 0;
findkDistinctNodePaths(root, freq,
distinct_nodes, k);
Console.Write(ans);
}
public static void Main(String[] args)
{
Node root = newNode(2);
root.left = newNode(1);
root.right = newNode(3);
root.left.left = newNode(4);
root.left.right = newNode(2);
root.right.left = newNode(-5);
root.right.right = newNode(3);
int K = 2;
printkDistinctNodePaths(root, K);
}
}
|
Javascript
<script>
class Node
{
constructor(key)
{
this .left = null ;
this .right = null ;
this .key = key;
}
}
let ans;
function newNode(key)
{
let temp = new Node(key);
return temp;
}
function findkDistinctNodePaths(root, freq,
distinct_nodes, k)
{
if (root == null )
return ;
if (!freq.has(root.key))
distinct_nodes++;
if (distinct_nodes > k)
return ;
if (freq.has(root.key))
{
freq.set(root.key,
freq.get(root.key) + 1);
}
else
{
freq.set(root.key, 1);
}
findkDistinctNodePaths(root.left, freq,
distinct_nodes, k);
findkDistinctNodePaths(root.right, freq,
distinct_nodes, k);
if (root.left == null &&
root.right == null )
{
if (distinct_nodes == k)
ans++;
}
}
function printkDistinctNodePaths(root, k)
{
let freq = new Map();
let distinct_nodes = 0;
ans = 0;
findkDistinctNodePaths(root, freq,
distinct_nodes, k);
document.write(ans);
}
let root = newNode(2);
root.left = newNode(1);
root.right = newNode(3);
root.left.left = newNode(4);
root.left.right = newNode(2);
root.right.left = newNode(-5);
root.right.right = newNode(3);
let K = 2;
printkDistinctNodePaths(root, K);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...