This approach utilizes a Depth First Search (DFS) to traverse each node of the tree. During traversal, we maintain a frequency array for each node to keep count of each label in its subtree. The recursion allows merging results from child nodes to calculate the current node's results.
The time complexity is O(n), where n is the number of nodes, because each node and edge is visited once during the DFS traversal. The space complexity is O(n), required for storing the graph representation and frequency arrays.
1#include <vector>
2#include <string>
3using namespace std;
4
5class Solution {
6public:
7 vector<int> countSubTrees(int n, vector<vector<int>>& edges, string labels) {
8 vector<vector<int>> graph(n);
9 for (const auto& edge : edges) {
10 graph[edge[0]].push_back(edge[1]);
11 graph[edge[1]].push_back(edge[0]);
12 }
13
14 vector<int> result(n, 0);
15 vector<vector<int>> count(n, vector<int>(26, 0));
16 dfs(0, -1, graph, labels, count, result);
17 return result;
18 }
19
20private:
21 void dfs(int node, int parent, vector<vector<int>>& graph, string& labels, vector<vector<int>>& count, vector<int>& result) {
22 int labelIndex = labels[node] - 'a';
23 count[node][labelIndex] = 1;
24 for (int child : graph[node]) {
25 if (child == parent) continue;
26 dfs(child, node, graph, labels, count, result);
27 for (int i = 0; i < 26; ++i) {
28 count[node][i] += count[child][i];
29 }
30 }
31 result[node] = count[node][labelIndex];
32 }
33};
This C++ solution also employs a DFS to traverse the tree. We build an adjacency list for the graph and use a frequency array for each node to track character counts in the subtree. In the DFS function, we recursively update the frequency array for the current node using the frequency arrays from its child nodes. The result for each node is set to the count of its label in its subtree.
This alternative approach utilizes a HashMap to dynamically manage counts of node labels as opposed to fixed-size arrays. The hash map structure allows potential extension to accommodate varying character sets, though for this problem, it's implemented for the fixed set of labels 'a' to 'z'.
The solution has a time complexity of O(n) given tree node analysis occurs once each during DFS with label counting operations. Space complexity is O(n), due to memory allocations for the graph and storage structures.
1import java.util.*;
2
3class Solution {
4 public int[] countSubTrees(int n, int[][] edges, String labels) {
5 List<List<Integer>> graph = new ArrayList<>();
6 for (int i = 0; i < n; i++) {
7 graph.add(new ArrayList<>());
8 }
9 for (int[] edge : edges) {
10 graph.get(edge[0]).add(edge[1]);
11 graph.get(edge[1]).add(edge[0]);
12 }
13
14 int[] result = new int[n];
15 List<Map<Character, Integer>> count = new ArrayList<>();
16 for (int i = 0; i < n; i++) {
17 count.add(new HashMap<>());
18 }
19 dfs(0, -1, graph, labels, count, result);
20 return result;
21 }
22
23 private void dfs(int node, int parent, List<List<Integer>> graph, String labels, List<Map<Character, Integer>> count, int[] result) {
24 char label = labels.charAt(node);
25 count.get(node).put(label, count.get(node).getOrDefault(label, 0) + 1);
26 for (int child : graph.get(node)) {
27 if (child == parent) continue;
28 dfs(child, node, graph, labels, count, result);
29 for (Map.Entry<Character, Integer> entry : count.get(child).entrySet()) {
30 count.get(node).put(entry.getKey(), count.get(node).getOrDefault(entry.getKey(), 0) + entry.getValue());
31 }
32 }
33 result[node] = count.get(node).get(label);
34 }
35}
Using Java's HashMap, this distinct solution counts label occurrences across a node’s subtree and propagates this information during DFS, integrating results dynamically based on computed child data. This flexible map-based approach effectively manages counts for each character encountered.