📌  相关文章
📜  计算在二叉树中具有恰好 K 个不同节点的根到叶路径

📅  最后修改于: 2021-09-06 05:23:38             🧑  作者: Mango

给定一个由N个以1为根的节点、一个整数K和一个由分配给每个节点的值组成的数组arr[]组成的二叉树,任务是计算给定二叉树中恰好有K 个不同节点的根到叶路径的数量树。

例子:

朴素的方法:最简单的方法是生成从根节点到叶节点的所有可能路径,对于每条路径,检查它是否包含K 个不同的节点。最后,打印这些路径的计数。

时间复杂度: O(N * H 2 ),其中 H 表示树的高度。
辅助空间: O(N);

高效方法:想法是使用 Preorder Traversal 和 Map 来计算从根到当前节点的路径中的不同节点。请按照以下步骤解决问题:

  • 将变量distinct_nodes初始化为0以存储从根到当前节点的不同节点的计数,并将ans初始化为0以存储具有K 个不同节点的不同根到叶路径的总数。
  • 在给定的二叉树中执行 Preorder Traversal 并将从根到当前节点的不同节点的计数存储在映射M 中
  • 每当节点第一次出现在路径上时,将不同节点的计数增加1
  • 如果路径上不同节点的数量大于K,则返回当前节点的父节点。
  • 否则,继续访问当前节点的子节点,将当前节点值的频率增加1
  • 在上面的步骤中,如果根到叶路径上不同节点的数量恰好等于K ,则将ans增加1
  • 在上述步骤之后,打印ans的值作为结果计数。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
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 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 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 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 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 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 freq = new Dictionary();
   
  // 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


输出:
2










时间复杂度: O(N)
辅助空间: O(N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live