# Solution For Number Of Nodes In The Sub Tree With The Same Label

Problem Statement:

Given a tree (an undirected connected graph with no cycles), each node of which is labeled with a distinct character, you need to count the number of nodes in a subtree with the same label.

Approach:

We can solve this problem using a depth-first search approach. We can traverse the tree using DFS and keep track of the count of characters encountered at each node. We can then return this count of characters to the parent node, where we can merge it with the counts of the different children nodes.

Algorithm:

First, we create an adjacency list representation of the given tree, where each node stores its label.

Next, we initialize a count map for each character, i.e., for each possible character in the given tree, we create a hashMap and initialize the count of that character to zero.

Now, we start traversing the tree using DFS, starting from the root node. For each node, we recursively call the DFS function on all its child nodes.

While traversing each child node, we store the count of each character encountered in a temp hashMap.

After processing all the child nodes, we add the count of the current node’s label to the temp hashMap.

We then return the temp hashMap to the parent node.

In the parent node, we merge the temp hashMap of all child nodes to get the count of each character in its subtree.

We update the global result hashMap with the count of nodes in the current node’s subtree with the same label.

Finally, we return the count of characters for the current node to its parent.

Pseudo Code:

# Initialize the result hashMap

resultHashMap = {}

# DFS function

def dfs(node):

# Initialize the temp hashMap

tempHashMap = {}

```
# Traverse all child nodes
for child in adjList[node]:
# Recursively call dfs on the child node
childHashMap = dfs(child)
# Update the temp hashMap with the count of characters in child nodes
for key in childHashMap:
if key not in tempHashMap:
tempHashMap[key] = childHashMap[key]
else:
tempHashMap[key] += childHashMap[key]
# Add the count of the current node's character to the temp hashMap
if nodeLabel in tempHashMap:
tempHashMap[nodeLabel] += 1
else:
tempHashMap[nodeLabel] = 1
# Update the global result hashMap with the count of nodes in the subtree with the same label
if nodeLabel in resultHashMap:
resultHashMap[nodeLabel] += tempHashMap[nodeLabel]
else:
resultHashMap[nodeLabel] = tempHashMap[nodeLabel]
# return the temp hashMap to the parent node
return tempHashMap
```

# Call dfs function on the root node

dfs(1)

# Print the count of nodes in the subtree with the same label for each node

for node in range(1,n+1):

print(resultHashMap[node])

Time Complexity:

The time complexity of the above algorithm is O(n), where n is the number of nodes in the given tree. We traverse each node once and process the count of characters in constant time using a hashMap.

Space Complexity:

The space complexity of the above algorithm is O(n), where n is the number of nodes in the given tree. We use a hashMap to store the count of characters encountered at each node and a hashMap to represent the adjacency list of the tree. Also, we use recursive stack space, which is equivalent to the height of the tree.

## Step by Step Implementation For Number Of Nodes In The Sub Tree With The Same Label

/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public int[] countSubTrees(int n, int[][] edges, String labels) { // create an adjacency list for the tree List> adjList = new ArrayList<>(); for (int i = 0; i < n; i++) { adjList.add(new ArrayList<>()); } for (int[] edge : edges) { int u = edge[0]; int v = edge[1]; adjList.get(u).add(v); adjList.get(v).add(u); } // dfs to count the number of nodes in the subtree with the same label int[] count = new int[n]; boolean[] visited = new boolean[n]; dfs(0, labels, adjList, count, visited); return count; } private int[] dfs(int u, String labels, List

> adjList, int[] count, boolean[] visited) { visited[u] = true; int[] curCount = new int[26]; curCount[labels.charAt(u) - 'a']++; for (int v : adjList.get(u)) { if (!visited[v]) { int[] subCount = dfs(v, labels, adjList, count, visited); for (int i = 0; i < 26; i++) { curCount[i] += subCount[i]; } } } count[u] = curCount[labels.charAt(u) - 'a']; return curCount; } }

def countSubTrees(self, n: int, edges: List[List[int]], labels: str) -> List[int]: # create a dictionary to store the counts of each label counts = collections.defaultdict(int) # create a dictionary to store the edges graph = collections.defaultdict(list) # add the edges to the dictionary for u, v in edges: graph[u].append(v) graph[v].append(u) # create a set to keep track of visited nodes visited = set() # create a queue to do a breadth first search queue = collections.deque() # add the root node to the queue queue.append(0) # do a breadth first search while queue: # get the node at the front of the queue node = queue.popleft() # if the node has not been visited if node not in visited: # add the node to the visited set visited.add(node) # for each edge connected to the node for neighbor in graph[node]: # add the edge to the queue queue.append(neighbor) # get the label of the node label = labels[node] # increment the count of the label counts[label] += 1 # return the list of counts return [counts[labels[node]] for node in range(n)]

var countSubTrees = function(n, edges, labels) { };

There are several ways to solve this problem. One approach would be to use a depth-first search algorithm to traverse the tree. For each node in the tree, we would keep track of the number of nodes in its subtree with the same label. We could then return the sum of these values for all nodes in the tree. Another approach would be to use a breadth-first search algorithm. We would keep track of the number of nodes at each level with the same label. We would then return the sum of these values for all nodes in the tree.

using System; class GFG { // A utility function to add an edge in an // undirected graph static void addEdge(int u, int v) { // Your code here } // A recursive function that // uses visited[] and parent to // detect cycle in subgraph reachable // from vertex v. static bool isCyclicUtil(int v, bool[] visited, int parent) { // Your code here } // Returns true if the graph contains // a cycle, else false. static bool isCyclic(int V) { // Your code here } // Driver code public static void Main() { int V = 5; // Add edges to the graph addEdge(1, 0); addEdge(0, 2); addEdge(2, 0); addEdge(0, 3); addEdge(3, 4); if (isCyclic(V)) Console.WriteLine("Graph contains cycle"); else Console.WriteLine("Graph doesn't " + "contain cycle"); } }