不一定是二叉树,共有n个节点,edges代表了互相连接的顶点形成的边,
每个节点有一个label, label是小写英文字母。
第 i 个字母表示第 i 个节点的标签。
问在同一子树中,相同标签的节点个数。
需要返回一个长度为n的数组,ans[i] 处的值表示在以节点i为根的子树中,和节点i 的标签相同的节点个数。
思路:
要找子树的每个节点的话,首先想到DFS。
现在的问题是怎么记录下子节点的label, 和这个label出现的次数。
可以用HashMap来记录,当然由于字母只有26个,可以用长度为26的数组记录下每个label出现的次数。
子节点遍历完之后,会得到一些字母上对应的次数>0了,
这个子树的根节点,要选出它的label对应的次数,放在ans[i]里面。
当然,首先还是要构建无向图,
然后要记录下每个节点是否已经被访问过,可以用visited数组记录,
由于没有环的存在,也可以只看child是不是上一节点即可。
class Solution {
List<Integer>[] graph;
int[] ans;
public int[] countSubTrees(int n, int[][] edges, String labels) {
graph = new ArrayList[n];
ans = new int[n];
HashSet<Character> chLabels = new HashSet<>();
for(int i = 0; i < n; i++) graph[i] = new ArrayList<>();
for(int[] edge : edges) {
graph[edge[0]].add(edge[1]);
graph[edge[1]].add(edge[0]);
}
chLabels.add(labels.charAt(0));
dfs(-1, 0, labels);
return ans;
}
int[] dfs(int pre, int node, String labels) {
int[] tmp = new int[26];
for(int child : graph[node]) {
if(pre == child) continue;
int[] res = dfs(node, child,labels);
for(int i = 0; i < 26; i++) tmp[i] += res[i];
}
ans[node] = ++tmp[labels.charAt(node)-'a'];
return tmp;
}
}