Number of Nodes in the Sub-Tree With the Same Label
Given a tree (i.e. a connected, undirected graph that has no cycles) consisting of n
nodes numbered from 0
to n - 1
and exactly n - 1
edges
. The root of the tree is the node 0
, and each node of the tree has a label which is a lower-case character given in the string labels
(i.e. The node with the number i
has the label labels[i]
).
The edges
array is given on the form edges[i] = [ai, bi]
, which means there is an edge between nodes ai
and bi
in the tree.
Return an array of size n
where ans[i]
is the number of nodes in the subtree of the ith
node which have the same label as node i
.
A subtree of a tree T
is the tree consisting of a node in T
and all of its descendant nodes.
Example 1:
Input: n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], labels = "abaedcd"
Output: [2,1,1,1,1,1,1]
Explanation: Node 0 has label 'a' and its sub-tree has node 2 with label 'a' as well, thus the answer is 2. Notice that any node is part of its sub-tree.
Node 1 has a label 'b'. The sub-tree of node 1 contains nodes 1,4 and 5, as nodes 4 and 5 have different labels than node 1, the answer is just
思路:这题其实就是个DFS的思路,每次往上传递char array的信息;但是build graph的时候,题目有个变态的case,[[0,2],[0,3],[1,2]] ,也就是边的信息不是那么的明确,谁是父节点,或者儿子节点,要用depth信息来判断;这个很恶心;这个题目出的水平不是很高,考察点很low,但是test cases很变态,所以不适合拿来面试;
class Solution {
private class Node {
public int index;
public Character c;
public int depth = 0;
public int[] chars;
public Node(int index, Character c, int depth) {
this.index = index;
this.c = c;
this.depth = depth;
this.chars = new int[26];
}
}
public int[] countSubTrees(int n, int[][] edges, String labels) {
if(edges == null || edges.length == 0 || edges[0].length == 0) {
return new int[0];
}
HashMap<Integer, Node> nodes = new HashMap<>();
for(int i = 0; i < n; i++) {
Node node = null;
char c = labels.charAt(i);
if(i == 0) {
node = new Node(i, c, 1);
node.chars[c - 'a'] = 1;
} else {
node = new Node(i, c, 0);
node.chars[c - 'a'] = 1;
}
nodes.put(i, node);
}
HashMap<Integer, List<Node>> graph = buildGraph(n, edges, labels, nodes);
dfs(0, graph, nodes);
int[] res = new int[n];
for(int i = 0; i < n; i++) {
Node node = nodes.get(i);
res[i] = node.chars[node.c - 'a'];
}
return res;
}
private Node dfs(int index, HashMap<Integer, List<Node>> graph, HashMap<Integer, Node> nodes) {
Node node = nodes.get(index);
for(Node neighbor: graph.get(index)) {
Node n = dfs(neighbor.index, graph, nodes);
for(int i = 0; i < 26; i++) {
node.chars[i] += n.chars[i];
}
}
return node;
}
private HashMap<Integer, List<Node>> buildGraph(int n, int[][] edges, String labels,
HashMap<Integer, Node> nodes ) {
HashMap<Integer, List<Node>> graph = new HashMap<>();
for(int i = 0; i < n; i++) {
graph.put(i, new ArrayList<Node>());
}
for(int i = 0; i < edges.length; i++) {
int a = edges[i][0];
int b = edges[i][1];
// a -> b;
if(nodes.get(a).depth > 0) {
nodes.get(b).depth = nodes.get(a).depth + 1;
graph.get(a).add(nodes.get(b));
} else {
nodes.get(a).depth = nodes.get(b).depth + 1;
graph.get(b).add(nodes.get(a));
}
}
return graph;
}
}