[LeetCode] 1519. Number of Nodes in the Sub-Tree With the Same Label

You are 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 1 (the node itself).

Example 2:

Input: n = 4, edges = [[0,1],[1,2],[0,3]], labels = "bbbb"
Output: [4,2,1,1]
Explanation: The sub-tree of node 2 contains only node 2, so the answer is 1.
The sub-tree of node 3 contains only node 3, so the answer is 1.
The sub-tree of node 1 contains nodes 1 and 2, both have label 'b', thus the answer is 2.
The sub-tree of node 0 contains nodes 0, 1, 2 and 3, all with label 'b', thus the answer is 4.

Example 3:

Input: n = 5, edges = [[0,1],[0,2],[1,3],[0,4]], labels = "aabab"
Output: [3,2,1,1,1]

Constraints:

  • 1 <= n <= 105
  • edges.length == n - 1
  • edges[i].length == 2
  • 0 <= ai, bi < n
  • ai != bi
  • labels.length == n
  • labels is consisting of only of lowercase English letters.

子树中标签相同的节点数。

给你一棵树(即,一个连通的无环无向图),这棵树由编号从 0  到 n - 1 的 n 个节点组成,且恰好有 n - 1 条 edges 。树的根节点为节点 0 ,树上的每一个节点都有一个标签,也就是字符串 labels 中的一个小写字符(编号为 i 的 节点的标签就是 labels[i] )

边数组 edges 以 edges[i] = [ai, bi] 的形式给出,该格式表示节点 ai 和 bi 之间存在一条边。

返回一个大小为 n 的数组,其中 ans[i] 表示第 i 个节点的子树中与节点 i 标签相同的节点数。

树 T 中的子树是由 T 中的某个节点及其所有后代节点组成的树。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/number-of-nodes-in-the-sub-tree-with-the-same-label
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路是后序遍历。注意题目给的是无环无向图,但是题目同时说了根节点是 0,所以其实这道题是有方向的。图中每个节点上都有一个字母,根据节点的 index 不同,每个节点上的字母也不尽相同。

首先我们还是要把这棵树用一个邻接表建立起来。接着我们从节点 0 开始做后序遍历。对于每一个父节点而言,我们先对他所有的子节点做 dfs 遍历,统计每个子节点上分别出现的是什么字母,然后用一个长度为 26 的数组记录下来。此时我们不要忘记,把当前这个父节点上的字母的出现次数也加进去,然后才能返回给当前节点的父节点。

最后附上一张图帮助理解(引用)。

时间O(n)

空间O(n)

Java实现

 1 class Solution {
 2     public int[] countSubTrees(int n, int[][] edges, String labels) {
 3         List<List<Integer>> g = new ArrayList<>();
 4         for (int i = 0; i < n; i++) {
 5             g.add(new ArrayList<>());
 6         }
 7         for (int[] e : edges) {
 8             g.get(e[0]).add(e[1]);
 9             g.get(e[1]).add(e[0]);
10         }
11         HashSet<Integer> visited = new HashSet<>();
12         visited.add(0);
13         int[] res = new int[n];
14         int[] count = dfs(0, g, labels, visited, res);
15         return res;
16     }
17 
18     private int[] dfs(int cur, List<List<Integer>> g, String labels, HashSet<Integer> visited, int[] res) {
19         // 以当前node为根节点能统计到多少字母
20         int[] count = new int[26];
21         List<Integer> children = g.get(cur);
22         char c = labels.charAt(cur);
23         for (Integer child : children) {
24             if (visited.add(child)) {
25                 int[] childDFS = dfs(child, g, labels, visited, res);
26                 for (int i = 0; i < 26; i++) {
27                     count[i] += childDFS[i];
28                 }
29             }
30         }
31         // 当前node上是什么字母
32         count[c - 'a']++;
33         res[cur] = count[c - 'a'];
34         return count;
35     }
36 }

 

LeetCode 题目总结

posted @ 2023-01-13 02:34  CNoodle  阅读(71)  评论(0编辑  收藏  举报