📜  n叉树中特殊节点的数量

📅  最后修改于: 2022-05-13 01:57:54.016000             🧑  作者: Mango

n叉树中特殊节点的数量

给定一棵以顶点 1 为根的 n 叉树。这棵树有 n 个顶点和 n-1 条边。每个节点都有一个与之关联的值,树以邻接表的形式输入。任务是找出树中特殊节点的数量。如果从根到节点的路径由不同的值节点组成,则节点是特殊的。
例子:

Input: val[] = {1, 2, 3, 4, 5, 7, 2, 3}
                1
               / \
              2   3
             / \   \
            4   5   7
               / \
              2   3
     
Output: 7
All nodes except the leaf node 2 are special.

Input: val[] = {2, 1, 4, 3, 4, 8, 10, 2, 5, 1}
                2
               / \
              1   4
            / \ \  \
           3  4  8  10
            / \ \
           2  5  1
    
Output: 8
Leaf nodes 2 and 1 are not special.

方法:这个想法是使用邻接表在给定的树上执行 dfs。在执行 dfs 插入集合中访问的节点的值时。如果当前节点的值已经存在于集合中,则当前节点和以当前节点为根的子树中的所有节点都不是特殊的。在遍历以当前节点为根的子树后,从集合中删除当前节点的值,因为该值或节点不在从根到所有其他未访问节点的路径上。
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// DFS function to traverse the tree and find
// number of special nodes
void dfs(int val[], int n, vector adj[], int v,
         unordered_set& values, int& ans)
{
 
    // If value of current node is already
    // present earlier in path then this
    // node and all other nodes connected to
    // it are not special
    if (values.count(val[v]))
        return;
 
    // Insert value of current node in
    // set of values traversed
    ans++;
    values.insert(val[v]);
 
    // Call dfs on all adjacent nodes
    for (auto ele : adj[v]) {
        dfs(val, n, adj, ele, values, ans);
    }
 
    // Erase value of current node as all paths
    // passing through current node are traversed
    values.erase(val[v]);
}
 
// Driver code
int main()
{
    int val[] = { 0, 2, 1, 4, 3, 4, 8, 10, 2, 5, 1 };
    int n = sizeof(val) / sizeof(val[0]);
 
    vector adj[n];
 
    adj[1].push_back(2);
    adj[1].push_back(3);
    adj[2].push_back(4);
    adj[2].push_back(5);
    adj[2].push_back(6);
    adj[3].push_back(7);
    adj[5].push_back(8);
    adj[5].push_back(9);
    adj[5].push_back(10);
 
    unordered_set values;
 
    int ans = 0;
 
    dfs(val, n, adj, 1, values, ans);
 
    cout << ans;
 
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
static int ans;
 
// DFS function to traverse the tree and find
// number of special nodes
static void dfs(int val[], int n, Vector adj[], int v,
        HashSet values)
{
 
    // If value of current node is already
    // present earlier in path then this
    // node and all other nodes connected to
    // it are not special
    if (values.contains(val[v]))
        return;
 
    // Insert value of current node in
    // set of values traversed
    ans++;
    values.add(val[v]);
 
    // Call dfs on all adjacent nodes
    for (int ele : adj[v])
    {
        dfs(val, n, adj, ele, values);
    }
 
    // Erase value of current node as all paths
    // passing through current node are traversed
    values.remove(val[v]);
}
 
// Driver code
public static void main(String[] args)
{
    int val[] = { 0, 2, 1, 4, 3, 4, 8, 10, 2, 5, 1 };
    int n = val.length;
 
    Vector []adj = new Vector[n];
    for(int i = 0; i < n ; i++)
    {
        adj[i] = new Vector();
    }
    adj[1].add(2);
    adj[1].add(3);
    adj[2].add(4);
    adj[2].add(5);
    adj[2].add(6);
    adj[3].add(7);
    adj[5].add(8);
    adj[5].add(9);
    adj[5].add(10);
 
    ans = 0;
    dfs(val, n, adj, 1, new HashSet());
    System.out.print(ans);
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 implementation of the approach
 
# DFS function to traverse the tree
# and find number of special nodes
def dfs(val, n, adj, v, values):
 
    # If value of current node is already
    # present earlier in path then this
    # node and all other nodes connected
    # to it are not special
    if val[v] in values:
        return
     
    global ans
 
    # Insert value of current node in
    # set of values traversed
    ans += 1
    values.add(val[v])
 
    # Call dfs on all adjacent nodes
    for ele in adj[v]:
        dfs(val, n, adj, ele, values)
 
    # Erase value of current node as all
    # paths passing through current node
    # are traversed
    values.remove(val[v])
 
# Driver code
if __name__ == "__main__":
 
    val = [0, 2, 1, 4, 3, 4, 8, 10, 2, 5, 1]
    n = len(val)
 
    adj = [[] for i in range(n)]
 
    adj[1].append(2)
    adj[1].append(3)
    adj[2].append(4)
    adj[2].append(5)
    adj[2].append(6)
    adj[3].append(7)
    adj[5].append(8)
    adj[5].append(9)
    adj[5].append(10)
 
    values = set()
    ans = 0
    dfs(val, n, adj, 1, values)
    print(ans)
 
# This code is contributed by Rituraj Jain


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG
{
  
static int ans;
  
// DFS function to traverse the tree and find
// number of special nodes
static void dfs(int []val, int n, List []adj, int v,
        HashSet values)
{
  
    // If value of current node is already
    // present earlier in path then this
    // node and all other nodes connected to
    // it are not special
    if (values.Contains(val[v]))
        return;
  
    // Insert value of current node in
    // set of values traversed
    ans++;
    values.Add(val[v]);
  
    // Call dfs on all adjacent nodes
    foreach (int ele in adj[v])
    {
        dfs(val, n, adj, ele, values);
    }
  
    // Erase value of current node as all paths
    // passing through current node are traversed
    values.Remove(val[v]);
}
  
// Driver code
public static void Main(String[] args)
{
    int []val = { 0, 2, 1, 4, 3, 4, 8, 10, 2, 5, 1 };
    int n = val.Length;
  
    List []adj = new List[n];
    for(int i = 0; i < n ; i++)
    {
        adj[i] = new List();
    }
    adj[1].Add(2);
    adj[1].Add(3);
    adj[2].Add(4);
    adj[2].Add(5);
    adj[2].Add(6);
    adj[3].Add(7);
    adj[5].Add(8);
    adj[5].Add(9);
    adj[5].Add(10);
  
    ans = 0;
    dfs(val, n, adj, 1, new HashSet());
    Console.Write(ans);
}
}
 
// This code is contributed by Rajput-Ji


Javascript


输出:
8

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