Count root to leaf paths having exactly K distinct nodes in a Binary Tree

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 Nodestruct Node {Â Â Â Â int key;Â Â Â Â Node *left, *right;};Â
// Function to create new tree nodeNode* 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 nodesvoid 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 nodevoid 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 Codeint 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 approachimport java.util.*;class GFG{Â
// Structure of a // Tree Nodestatic class Node {Â Â int key;Â Â Node left, right;};Â Â Â static int ans;Â Â Â // Function to create // new tree nodestatic 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 nodesstatic 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 nodestatic 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 Codepublic 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 Nodeclass 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 nodesdef 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 nodedef 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 Codeif __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 approachusing System;using System.Collections.Generic;Â
class GFG{Â
// Structure of a // Tree Nodepublic class Node {  public int key;  public Node left, right;};   static int ans;   // Function to create // new tree nodestatic 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 nodesstatic 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 nodestatic 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 Codepublic 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 nodeclass Node{Â Â Â Â constructor(key)Â Â Â Â {Â Â Â Â Â Â Â Â this.left = null;Â Â Â Â Â Â Â Â this.right = null;Â Â Â Â Â Â Â Â this.key = key;Â Â Â Â }}Â
let ans;Â
// Function to create// new tree nodefunction newNode(key){Â Â Â Â let temp = new Node(key);Â Â Â Â return temp;}Â
// Function to count all root// to leaf paths having K// distinct nodesfunction 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 nodefunction 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 Treelet 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 Klet K = 2;Â
// Function CallprintkDistinctNodePaths(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 zambiatek!




