Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9478ef0

Browse files
Merge pull request SharingSource#404 from SharingSource/ac_oier
✨feat: Add 2049
2 parents de628f1 + 75a70b2 commit 9478ef0

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

‎Index/图论 DFS.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
| [1034. 边界着色](https://leetcode-cn.com/problems/coloring-a-border/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/coloring-a-border/solution/gong-shui-san-xie-tu-lun-sou-suo-zhuan-t-snvw/) | 中等 | 🤩🤩🤩🤩 |
99
| [1723. 完成所有工作的最短时间](https://leetcode-cn.com/problems/find-minimum-time-to-finish-all-jobs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-minimum-time-to-finish-all-jobs/solution/gong-shui-san-xie-yi-ti-shuang-jie-jian-4epdd/) | 困难 | 🤩🤩🤩 |
1010
| [1766. 互质树](https://leetcode-cn.com/problems/tree-of-coprimes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/tree-of-coprimes/solution/bu-tai-yi-yang-de-dfs-ji-lu-suo-you-zui-d3xeu/) | 困难 | 🤩🤩🤩🤩 |
11+
| [2049. 统计最高分的节点数目](https://leetcode-cn.com/problems/count-nodes-with-the-highest-score/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/count-nodes-with-the-highest-score/solution/gong-shui-san-xie-jian-tu-dfs-by-ac_oier-ujfo/) | 中等 | 🤩🤩🤩🤩 |
1112
| [LCP 07. 传递信息](https://leetcode-cn.com/problems/chuan-di-xin-xi/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/chuan-di-xin-xi/solution/gong-shui-san-xie-tu-lun-sou-suo-yu-dong-cyxo/) | 简单 | 🤩🤩🤩🤩 |
1213

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[2049. 统计最高分的节点数目](https://leetcode-cn.com/problems/count-nodes-with-the-highest-score/solution/gong-shui-san-xie-jian-tu-dfs-by-ac_oier-ujfo/)** ,难度为 **中等**
4+
5+
Tag : 「图论」、「线性 DP」
6+
7+
8+
9+
给你一棵根节点为 0ドル$ 的 二叉树 ,它总共有 $n$ 个节点,节点编号为 0ドル$ 到 $n - 1$ 。
10+
11+
同时给你一个下标从 0ドル$ 开始的整数数组 $parents$ 表示这棵树,其中 $parents[i]$ 是节点 $i$ 的父节点。由于节点 0ドル$ 是根,所以 $parents[0] == -1$ 。
12+
13+
一个子树的 **大小** 为这个子树内节点的数目。每个节点都有一个与之关联的 **分数** 。求出某个节点分数的方法是,将这个节点和与它相连的边全部 **删除** ,剩余部分是若干个 **非空** 子树,这个节点的 **分数** 为所有这些子树 大小的乘积 。
14+
15+
请你返回有 **最高得分** 节点的 数目 。
16+
17+
示例 1:
18+
![](https://assets.leetcode.com/uploads/2021/10/03/example-1.png)
19+
```
20+
输入:parents = [-1,2,0,2,0]
21+
22+
输出:3
23+
24+
解释:
25+
- 节点 0 的分数为:3 * 1 = 3
26+
- 节点 1 的分数为:4 = 4
27+
- 节点 2 的分数为:1 * 1 * 2 = 2
28+
- 节点 3 的分数为:4 = 4
29+
- 节点 4 的分数为:4 = 4
30+
最高得分为 4 ,有三个节点得分为 4 (分别是节点 1,3 和 4 )。
31+
```
32+
示例 2:
33+
![](https://assets.leetcode.com/uploads/2021/10/03/example-2.png)
34+
35+
```
36+
输入:parents = [-1,2,0]
37+
38+
输出:2
39+
40+
解释:
41+
- 节点 0 的分数为:2 = 2
42+
- 节点 1 的分数为:2 = 2
43+
- 节点 2 的分数为:1 * 1 = 1
44+
最高分数为 2 ,有两个节点分数为 2 (分别为节点 0 和 1 )。
45+
```
46+
47+
提示:
48+
* $n == parents.length$
49+
* 2ドル <= n <= 10^5$
50+
* $parents[0] == -1$
51+
* 对于 $i != 0$ ,有 0ドル <= parents[i] <= n - 1$
52+
* $parents$ 表示一棵二叉树。
53+
54+
---
55+
56+
### 建图 + DFS
57+
58+
为了更具有一般性,我们假定该树为多叉树。
59+
60+
由于题目给定的 `parents` 数组仅支持我们快速查找某个节点的父节点,为了方便遍历整棵树,我们先使用「邻接表」将图(树)建起来。
61+
62+
然后使用 `DFS` 预处理出 `f` 数组,其中 $f[i]$ 代表以节点 $i$ 为根节点的子树所包含的节点数量。
63+
64+
考虑如何计算「删除某个节点 $x$ 后,剩余连通块的数量,以及每个连通块的节点数量」,根据节点 $x$ 是否为根节点进行分情况讨论:
65+
66+
* 若 $x$ 为根节点,删除后的连通块的数量为「$x$ 的出边数量」,假定共有 $k$ 条出边,根据题目定义,对应的 **大小** 为各个连通块的节点数量乘积:
67+
$$
68+
f[u_1] \times f[u_2] \times ... \times f[u_k]
69+
$$
70+
71+
* 若 $x$ 不是根节点,删除后的连通块的数量为「$x$ 的出边数量 + 1ドル$」,其中 1ドル$ 代指「以 $x$ 节点的父节点所在的整体连通块」。
72+
73+
假定节点 $x$ 共有 $k$ 条出边,根据题目定义,对应的 **大小** 为「(各个连通块的节点数量乘积) $\times$ ($x$ 节点的父节点所在的整体连通块大小)」,而「$x$ 节点的父节点所在的整体连通块大小」,利用容斥原理可知为 $f[root] - f[u] = n - f[u],ドル含义为「从原树中减掉以节点 $x$ 为根节点的子树」的部分,即最终 **大小** 为:
74+
$$
75+
(f[u_1] \times f[u_2] \times ... \times f[u_k]) \times (n - f[x])
76+
$$
77+
78+
代码:
79+
```Java
80+
class Solution {
81+
static int N = 100010, M = N * 2;
82+
static int[] he = new int[N], e = new int[M], ne = new int[M];
83+
static int[] f = new int[N];
84+
int idx;
85+
void add(int a, int b) {
86+
e[idx] = b;
87+
ne[idx] = he[a];
88+
he[a] = idx++;
89+
}
90+
public int countHighestScoreNodes(int[] parents) {
91+
Arrays.fill(he, -1);
92+
int n = parents.length;
93+
for (int i = 1; i < n; i++) add(parents[i], i);
94+
dfs(0);
95+
long max = 0;
96+
int ans = 0;
97+
for (int x = 0; x < n; x++) {
98+
long cur = 1;
99+
for (int i = he[x]; i != -1; i = ne[i]) cur *= f[e[i]];
100+
if (x != 0) cur *= n - f[x];
101+
if (cur > max) {
102+
max = cur; ans = 1;
103+
} else if (cur == max) {
104+
ans++;
105+
}
106+
}
107+
return ans;
108+
}
109+
int dfs(int u) {
110+
int ans = 1;
111+
for (int i = he[u]; i != -1; i = ne[i]) ans += dfs(e[i]);
112+
f[u] = ans;
113+
return ans;
114+
}
115+
}
116+
```
117+
* 时间复杂度:建图复杂度为 $O(n)$;通过 `DFS` 预处理 `f` 数组复杂度为 $O(n + m),ドル其中 $m$ 为边数,对于本题(二叉树)而言,点边数量级相等,因此 `DFS` 预处理的复杂度为 $O(n)$;模拟删除任意点并统计答案的复杂度为 $O(n + m),ドル对于本题(二叉树)而言,数量级为 $O(n)$。整体复杂度为 $O(n)$
118+
* 空间复杂度:$O(n)$
119+
120+
---
121+
122+
### 最后
123+
124+
这是我们「刷穿 LeetCode」系列文章的第 `No.2049` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
125+
126+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
127+
128+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
129+
130+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
131+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /