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++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; Â
// Structure of a Tree Node struct Node { Â Â Â Â int key; Â Â Â Â Node *left, *right; }; Â
// Function to create new tree node Node* newNode( int key) { Â Â Â Â Node* temp = new Node; Â Â Â Â temp->key = key; Â Â Â Â temp->left = temp->right = NULL; Â Â Â Â return temp; } Â
// Function to count all root to leaf // paths having K distinct nodes void findkDistinctNodePaths(     Node* root, unordered_map< int , int > freq,     int distinct_nodes, int k, int & ans) {     // If current node is null     if (root == NULL)         return ; Â
    // Update count of distinct nodes     if (freq[root->key] == 0)         distinct_nodes++; Â
    // If count > k then return to     // the parent node     if (distinct_nodes > k)         return ; Â
    // Update frequency of current node     freq[root->key]++; Â
    // Go to the left subtree     findkDistinctNodePaths(root->left,                            freq,                            distinct_nodes,                            k, ans); Â
    // Go to the right subtree     findkDistinctNodePaths(root->right,                            freq,                            distinct_nodes,                            k, ans); Â
    // If current node is leaf node     if (root->left == NULL         && root->right == NULL) { Â
        // If count of distinct node         // is same as K, increment ans         if (distinct_nodes == k)             ans++;     } } Â
// Function to find count of root to // leaf paths having K distinct node void printkDistinctNodePaths(Node* root,                              int k) {     // Initialize unordered map     unordered_map< int , int > freq; Â
    // Stores count of distinct node     int distinct_nodes = 0; Â
    // Stores total count of nodes     int ans = 0; Â
    // Perform Preorder Traversal     findkDistinctNodePaths(root, freq,                            distinct_nodes,                            k, ans); Â
    // Print the final count     cout << ans; } Â
// Driver Code int main() { Â Â Â Â /*Â Â Â Â Â Â Â Â 2 Â Â Â Â Â Â Â Â Â Â Â Â Â /Â Â \ Â Â Â Â Â Â Â Â Â Â Â Â /Â Â Â Â \ Â Â Â Â Â Â Â Â Â Â Â 1Â Â Â Â Â Â 3 Â Â Â Â Â Â Â Â Â Â / \Â Â Â Â /Â \ Â Â Â Â Â Â Â Â Â /Â Â \Â Â /Â Â Â \ Â Â Â Â Â Â Â Â 4Â Â Â Â 2 -5Â Â Â Â 3 Â Â Â Â */ Â
    // Given Binary Tree     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); Â
    // Given K     int K = 2; Â
    // Function Call     printkDistinctNodePaths(root, K); Â
    return 0; } |
Java
// Java program for the // above approach import java.util.*; class GFG{ Â
// Structure of a // Tree Node static class Node { Â Â int key; Â Â Node left, right; }; Â Â Â static int ans; Â Â Â // Function to create // new tree node static Node newNode( int key) { Â Â Node temp = new Node(); Â Â temp.key = key; Â Â temp.left = temp.right = null ; Â Â return temp; } Â
// Function to count all root // to leaf paths having K // distinct nodes static void findkDistinctNodePaths(Node root,                                    HashMap<Integer,                                            Integer> freq,                                    int distinct_nodes,                                    int k) {   // If current node is null   if (root == null )     return ; Â
  // Update count of distinct nodes   if (!freq.containsKey(root.key))     distinct_nodes++; Â
  // If count > k then return   // to the parent node   if (distinct_nodes > k)     return ; Â
  // Update frequency of   // current node   if (freq.containsKey(root.key))   {     freq.put(root.key,     freq.get(root.key) + 1 );   }   else   {     freq.put(root.key, 1 );   } Â
  // Go to the left subtree   findkDistinctNodePaths(root.left, freq,                          distinct_nodes, k); Â
  // Go to the right subtree   findkDistinctNodePaths(root.right, freq,                          distinct_nodes, k); Â
  // If current node is   // leaf node   if (root.left == null &&       root.right == null )   {     // If count of distinct node     // is same as K, increment ans     if (distinct_nodes == k)       ans++;   } } Â
// Function to find count of root to // leaf paths having K distinct node static void printkDistinctNodePaths(Node root,                                     int k) {   // Initialize unordered map   HashMap<Integer,           Integer> freq = new HashMap<>(); Â
  // Stores count of   // distinct node   int distinct_nodes = 0 ; Â
  // Stores total   // count of nodes   ans = 0 ; Â
  // Perform Preorder Traversal   findkDistinctNodePaths(root, freq,                          distinct_nodes, k); Â
  // Print the final count   System.out.print(ans); } Â
// Driver Code public static void main(String[] args) { Â Â /*Â Â Â Â Â Â Â Â Â Â 2 Â Â Â Â Â Â Â Â Â Â Â Â Â /Â Â \ Â Â Â Â Â Â Â Â Â Â Â Â /Â Â Â Â \ Â Â Â Â Â Â Â Â Â Â Â 1Â Â Â Â Â Â 3 Â Â Â Â Â Â Â Â Â Â / \Â Â Â Â /Â \ Â Â Â Â Â Â Â Â Â /Â Â \Â Â /Â Â Â \ Â Â Â Â Â Â Â Â 4Â Â Â Â 2 -5Â Â Â Â 3 Â Â Â Â */ Â
  // Given Binary Tree   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 ); Â
  // Given K   int K = 2 ; Â
  // Function Call   printkDistinctNodePaths(root, K); } } Â
// This code is contributed by gauravrajput1 |
Python3
# Python3 program for the above approach Â
# Structure of a Tree Node class newNode:          def __init__( self , key):                  self .key = key         self .left = None         self .right = None Â
ans = 0 Â
# Function to count all root to leaf # paths having K distinct nodes def findkDistinctNodePaths(root, freq,                            distinct_nodes, k):                                     global ans          # If current node is None     if (root = = None ):         return Â
    # Update count of distinct nodes     if (root.key not in freq):         distinct_nodes + = 1 Â
    # If count > k then return to     # the parent node     if (distinct_nodes > k):         return Â
    # Update frequency of current node     if (root.key in freq):         freq[root.key] + = 1     else :         freq[root.key] = freq.get(root.key, 0 ) + 1 Â
    # Go to the left subtree     findkDistinctNodePaths(root.left, freq,                            distinct_nodes, k) Â
    # Go to the right subtree     findkDistinctNodePaths(root.right, freq,                            distinct_nodes, k) Â
    # If current node is leaf node     if (root.left = = None and        root.right = = None ):                  # If count of distinct node         # is same as K, increment ans         if (distinct_nodes = = k):             ans + = 1 Â
# Function to find count of root to # leaf paths having K distinct node def printkDistinctNodePaths(root, k):          global ans          # Initialize unordered map     freq = {} Â
    # Stores count of distinct node     distinct_nodes = 0 Â
    # Perform Preorder Traversal     findkDistinctNodePaths(root, freq,                            distinct_nodes, k) Â
    # Print the final count     print (ans) Â
# Driver Code if __name__ = = '__main__' : Â Â Â Â Â Â Â Â Â '''Â Â Â Â Â Â Â 2 Â Â Â Â Â Â Â Â Â Â Â Â Â /Â Â \ Â Â Â Â Â Â Â Â Â Â Â Â /Â Â Â Â \ Â Â Â Â Â Â Â Â Â Â Â 1Â Â Â Â Â Â 3 Â Â Â Â Â Â Â Â Â Â / \Â Â Â Â /Â \ Â Â Â Â Â Â Â Â Â /Â Â \Â Â /Â Â Â \ Â Â Â Â Â Â Â Â 4Â Â Â Â 2 -5Â Â Â Â 3 Â Â Â Â ''' Â
    # Given Binary Tree     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 ) Â
    # Given K     K = 2 Â
    # Function Call     printkDistinctNodePaths(root, K)      # This code is contributed by SURENDRA_GANGWAR |
C#
// C# program for the // above approach using System; using System.Collections.Generic; Â
class GFG{ Â
// Structure of a // Tree Node public class Node {   public int key;   public Node left, right; };    static int ans;    // Function to create // new tree node static Node newNode( int key) {   Node temp = new Node();   temp.key = key;   temp.left = temp.right = null ;   return temp; }    // Function to count all root // to leaf paths having K // distinct nodes static void findkDistinctNodePaths(Node root,                                    Dictionary< int , int > freq,                                    int distinct_nodes,                                    int k) {      // If current node is null   if (root == null )     return ; Â
  // Update count of distinct nodes   if (!freq.ContainsKey(root.key))     distinct_nodes++; Â
  // If count > k then return   // to the parent node   if (distinct_nodes > k)     return ; Â
  // Update frequency of   // current node   if (freq.ContainsKey(root.key))   {     freq[root.key] = freq[root.key] + 1;   }   else   {     freq.Add(root.key, 1);   } Â
  // Go to the left subtree   findkDistinctNodePaths(root.left, freq,                          distinct_nodes, k); Â
  // Go to the right subtree   findkDistinctNodePaths(root.right, freq,                          distinct_nodes, k); Â
  // If current node is   // leaf node   if (root.left == null &&       root.right == null )   {          // If count of distinct node     // is same as K, increment ans     if (distinct_nodes == k)       ans++;   } } Â
// Function to find count of root to // leaf paths having K distinct node static void printkDistinctNodePaths(Node root,                                     int k) {      // Initialize unordered map   Dictionary< int ,              int > freq = new Dictionary< int ,                                         int >();      // Stores count of   // distinct node   int distinct_nodes = 0; Â
  // Stores total   // count of nodes   ans = 0; Â
  // Perform Preorder Traversal   findkDistinctNodePaths(root, freq,                          distinct_nodes, k); Â
  // Print the readonly count   Console.Write(ans); } Â
// Driver Code public static void Main(String[] args) { Â Â /*Â Â Â Â Â Â Â Â Â Â 2 Â Â Â Â Â Â Â Â Â Â Â Â Â /Â Â \ Â Â Â Â Â Â Â Â Â Â Â Â /Â Â Â Â \ Â Â Â Â Â Â Â Â Â Â Â 1Â Â Â Â Â Â 3 Â Â Â Â Â Â Â Â Â Â / \Â Â Â Â /Â \ Â Â Â Â Â Â Â Â Â /Â Â \Â Â /Â Â Â \ Â Â Â Â Â Â Â Â 4Â Â Â Â 2 -5Â Â Â Â 3 Â Â Â Â */ Â
  // Given Binary Tree   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); Â
  // Given K   int K = 2; Â
  // Function Call   printkDistinctNodePaths(root, K); } } Â
// This code is contributed by Princi Singh |
Javascript
<script> Â
// Javascript program for the above approach Â
// Structure of tree node class Node { Â Â Â Â constructor(key) Â Â Â Â { Â Â Â Â Â Â Â Â this .left = null ; Â Â Â Â Â Â Â Â this .right = null ; Â Â Â Â Â Â Â Â this .key = key; Â Â Â Â } } Â
let ans; Â
// Function to create // new tree node function newNode(key) { Â Â Â Â let temp = new Node(key); Â Â Â Â return temp; } Â
// Function to count all root // to leaf paths having K // distinct nodes function findkDistinctNodePaths(root, freq,                                 distinct_nodes, k) {          // If current node is null     if (root == null )         return ;          // Update count of distinct nodes     if (!freq.has(root.key))         distinct_nodes++;          // If count > k then return     // to the parent node     if (distinct_nodes > k)         return ;          // Update frequency of     // current node     if (freq.has(root.key))     {         freq.set(root.key,         freq.get(root.key) + 1);     }     else     {         freq.set(root.key, 1);     }          // Go to the left subtree     findkDistinctNodePaths(root.left, freq,                            distinct_nodes, k);          // Go to the right subtree     findkDistinctNodePaths(root.right, freq,                            distinct_nodes, k);          // If current node is     // leaf node     if (root.left == null &&         root.right == null )     {                  // If count of distinct node         // is same as K, increment ans         if (distinct_nodes == k)             ans++;     } } Â
// Function to find count of root to // leaf paths having K distinct node function printkDistinctNodePaths(root, k) {          // Initialize unordered map     let freq = new Map();          // Stores count of     // distinct node     let distinct_nodes = 0;          // Stores total     // count of nodes     ans = 0;          // Perform Preorder Traversal     findkDistinctNodePaths(root, freq,                            distinct_nodes, k);          // Print the final count     document.write(ans); } Â
// Driver code /*Â Â Â Â Â Â Â Â 2 Â Â Â Â Â Â Â Â Â /Â Â \ Â Â Â Â Â Â Â Â /Â Â Â Â \ Â Â Â Â Â Â Â 1Â Â Â Â Â Â 3 Â Â Â Â Â Â / \Â Â Â Â /Â \ Â Â Â Â Â /Â Â \Â Â /Â Â Â \ Â Â Â Â 4Â Â Â Â 2 -5Â Â Â Â 3 */ Â
// Given Binary Tree 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); Â
// Given K let K = 2; Â
// Function Call printkDistinctNodePaths(root, K); Â
// This code is contributed by suresh07 Â
</script> |
2
Â
Time Complexity: O(N)
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!