Skip to content

Commit 051a58b

Browse files
authored
feat: add solutions to lc problem: No.3004 (doocs#2206)
No.3004.Maximum Subtree of the Same Color
1 parent 469775b commit 051a58b

File tree

11 files changed

+658
-0
lines changed

11 files changed

+658
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
# [3004. Maximum Subtree of the Same Color](https://leetcode.cn/problems/maximum-subtree-of-the-same-color)
2+
3+
[English Version](/solution/3000-3099/3004.Maximum%20Subtree%20of%20the%20Same%20Color/README_EN.md)
4+
5+
## 题目描述
6+
7+
<!-- 这里写题目描述 -->
8+
9+
<p>You are given a 2D integer array <code>edges</code> representing a tree with <code>n</code> nodes, numbered from <code>0</code> to <code>n - 1</code>, rooted at node <code>0</code>, where <code>edges[i] = [u<sub>i</sub>, v<sub>i</sub>]</code> means there is an edge between the nodes <code>v<sub>i</sub></code> and <code>u<sub>i</sub></code>.</p>
10+
11+
<p>You are also given a <strong>0-indexed</strong> integer array <code>colors</code> of size <code>n</code>, where <code>colors[i]</code> is the color assigned to node <code>i</code>.</p>
12+
13+
<p>We want to find a node <code>v</code> such that every node in the <span data-keyword="subtree-of-node">subtree</span> of <code>v</code> has the <strong>same</strong> color.</p>
14+
15+
<p>Return <em>the size of such subtree with the <strong>maximum</strong> number of nodes possible.</em></p>
16+
17+
<p>&nbsp;</p>
18+
<p><strong><img alt="" src="https://assets.leetcode.com/static_assets/others/20231216-134026.png" style="padding: 10px; background: rgb(255, 255, 255); border-radius: 0.5rem; width: 221px; height: 132px;" /></strong></p>
19+
20+
<p><strong class="example">Example 1:</strong></p>
21+
22+
<pre>
23+
<strong>Input:</strong> edges = [[0,1],[0,2],[0,3]], colors = [1,1,2,3]
24+
<strong>Output:</strong> 1
25+
<strong>Explanation:</strong> Each color is represented as: 1 -&gt; Red, 2 -&gt; Green, 3 -&gt; Blue. We can see that the subtree rooted at node 0 has children with different colors. Any other subtree is of the same color and has a size of 1. Hence, we return 1.
26+
</pre>
27+
28+
<p><strong class="example">Example 2:</strong></p>
29+
30+
<pre>
31+
<strong>Input:</strong> edges = [[0,1],[0,2],[0,3]], colors = [1,1,1,1]
32+
<strong>Output:</strong> 4
33+
<strong>Explanation:</strong> The whole tree has the same color, and the subtree rooted at node 0 has the most number of nodes which is 4. Hence, we return 4.
34+
</pre>
35+
36+
<p><strong><img alt="" src="https://assets.leetcode.com/static_assets/others/20231216-134017.png" style="padding: 10px; background: rgb(255, 255, 255); border-radius: 0.5rem; width: 221px; height: 221px;" /></strong></p>
37+
38+
<p><strong class="example">Example 3:</strong></p>
39+
40+
<pre>
41+
<strong>Input:</strong> edges = [[0,1],[0,2],[2,3],[2,4]], colors = [1,2,3,3,3]
42+
<strong>Output:</strong> 3
43+
<strong>Explanation:</strong> Each color is represented as: 1 -&gt; Red, 2 -&gt; Green, 3 -&gt; Blue. We can see that the subtree rooted at node 0 has children with different colors. Any other subtree is of the same color, but the subtree rooted at node 2 has a size of 3 which is the maximum. Hence, we return 3.
44+
</pre>
45+
46+
<p>&nbsp;</p>
47+
<p><strong>Constraints:</strong></p>
48+
49+
<ul>
50+
<li><code>n == edges.length + 1</code></li>
51+
<li><code>1 &lt;= n &lt;= 5 * 10<sup>4</sup></code></li>
52+
<li><code>edges[i] == [u<sub>i</sub>, v<sub>i</sub>]</code></li>
53+
<li><code>0 &lt;= u<sub>i</sub>, v<sub>i</sub> &lt; n</code></li>
54+
<li><code>colors.length == n</code></li>
55+
<li><code>1 &lt;= colors[i] &lt;= 10<sup>5</sup></code></li>
56+
<li>The input is generated such that the graph represented by <code>edges</code> is a tree.</li>
57+
</ul>
58+
59+
## 解法
60+
61+
<!-- 这里可写通用的实现逻辑 -->
62+
63+
**方法一:DFS**
64+
65+
我们先根据题目给定的边的信息,构建一个邻接表 $g$,其中 $g[a]$ 表示节点 $a$ 的所有相邻节点。然后我们创建一个长度为 $n$ 的数组 $size$,其中 $size[a]$ 表示以节点 $a$ 为根的子树的节点数。
66+
67+
接下来,我们设计一个函数 $dfs(a, fa)$,它将返回以节点 $a$ 为根的子树是否满足题目要求。函数 $dfs(a, fa)$ 的执行过程如下:
68+
69+
- 首先,我们用一个变量 $ok$ 记录以节点 $a$ 为根的子树是否满足题目要求,初始时 $ok$ 为 $true$。
70+
- 接着,我们遍历节点 $a$ 的所有相邻节点 $b$,如果 $b$ 不是 $a$ 的父节点 $fa$,那么我们递归调用 $dfs(b, a)$,并将返回值保存到变量 $t$ 中,并且更新 $ok$ 为 $ok$ 与 $colors[a] = colors[b] \land t$ 的值,其中 $\land$ 表示逻辑与运算。然后,我们更新 $size[a] = size[a] + size[b]$。
71+
- 然后,我们判断 $ok$ 的值,如果 $ok$ 为 $true$,那么我们更新答案 $ans = \max(ans, size[a])$。
72+
- 最后,我们返回 $ok$ 的值。
73+
74+
我们调用 $dfs(0, -1)$,其中 $0$ 表示根节点的编号,$-1$ 表示根节点没有父节点。最终的答案即为 $ans$。
75+
76+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是节点的数量。
77+
78+
<!-- tabs:start -->
79+
80+
### **Python3**
81+
82+
<!-- 这里可写当前语言的特殊实现逻辑 -->
83+
84+
```python
85+
class Solution:
86+
def maximumSubtreeSize(self, edges: List[List[int]], colors: List[int]) -> int:
87+
def dfs(a: int, fa: int) -> bool:
88+
ok = True
89+
for b in g[a]:
90+
if b != fa:
91+
t = dfs(b, a)
92+
ok = ok and colors[a] == colors[b] and t
93+
size[a] += size[b]
94+
if ok:
95+
nonlocal ans
96+
ans = max(ans, size[a])
97+
return ok
98+
99+
n = len(edges) + 1
100+
g = [[] for _ in range(n)]
101+
size = [1] * n
102+
for a, b in edges:
103+
g[a].append(b)
104+
g[b].append(a)
105+
ans = 0
106+
dfs(0, -1)
107+
return ans
108+
```
109+
110+
### **Java**
111+
112+
<!-- 这里可写当前语言的特殊实现逻辑 -->
113+
114+
```java
115+
class Solution {
116+
private List<Integer>[] g;
117+
private int[] colors;
118+
private int[] size;
119+
private int ans;
120+
121+
public int maximumSubtreeSize(int[][] edges, int[] colors) {
122+
int n = edges.length + 1;
123+
g = new List[n];
124+
size = new int[n];
125+
this.colors = colors;
126+
Arrays.fill(size, 1);
127+
Arrays.setAll(g, i -> new ArrayList<>());
128+
for (var e : edges) {
129+
int a = e[0], b = e[1];
130+
g[a].add(b);
131+
g[b].add(a);
132+
}
133+
dfs(0, -1);
134+
return ans;
135+
}
136+
137+
private boolean dfs(int a, int fa) {
138+
boolean ok = true;
139+
for (int b : g[a]) {
140+
if (b != fa) {
141+
boolean t = dfs(b, a);
142+
ok = ok && colors[a] == colors[b] && t;
143+
size[a] += size[b];
144+
}
145+
}
146+
if (ok) {
147+
ans = Math.max(ans, size[a]);
148+
}
149+
return ok;
150+
}
151+
}
152+
```
153+
154+
### **C++**
155+
156+
```cpp
157+
class Solution {
158+
public:
159+
int maximumSubtreeSize(vector<vector<int>>& edges, vector<int>& colors) {
160+
int n = edges.size() + 1;
161+
vector<int> g[n];
162+
vector<int> size(n, 1);
163+
for (auto& e : edges) {
164+
int a = e[0], b = e[1];
165+
g[a].push_back(b);
166+
g[b].push_back(a);
167+
}
168+
int ans = 0;
169+
function<bool(int, int)> dfs = [&](int a, int fa) {
170+
bool ok = true;
171+
for (int b : g[a]) {
172+
if (b != fa) {
173+
bool t = dfs(b, a);
174+
ok = ok && colors[a] == colors[b] && t;
175+
size[a] += size[b];
176+
}
177+
}
178+
if (ok) {
179+
ans = max(ans, size[a]);
180+
}
181+
return ok;
182+
};
183+
dfs(0, -1);
184+
return ans;
185+
}
186+
};
187+
```
188+
189+
### **Go**
190+
191+
```go
192+
func maximumSubtreeSize(edges [][]int, colors []int) (ans int) {
193+
n := len(edges) + 1
194+
g := make([][]int, n)
195+
for _, e := range edges {
196+
a, b := e[0], e[1]
197+
g[a] = append(g[a], b)
198+
g[b] = append(g[b], a)
199+
}
200+
size := make([]int, n)
201+
var dfs func(int, int) bool
202+
dfs = func(a, fa int) bool {
203+
size[a] = 1
204+
ok := true
205+
for _, b := range g[a] {
206+
if b != fa {
207+
t := dfs(b, a)
208+
ok = ok && t && colors[a] == colors[b]
209+
size[a] += size[b]
210+
}
211+
}
212+
if ok {
213+
ans = max(ans, size[a])
214+
}
215+
return ok
216+
}
217+
dfs(0, -1)
218+
return
219+
}
220+
```
221+
222+
### **TypeScript**
223+
224+
```ts
225+
function maximumSubtreeSize(edges: number[][], colors: number[]): number {
226+
const n = edges.length + 1;
227+
const g: number[][] = Array.from({ length: n }, () => []);
228+
for (const [a, b] of edges) {
229+
g[a].push(b);
230+
g[b].push(a);
231+
}
232+
const size: number[] = Array(n).fill(1);
233+
let ans = 0;
234+
const dfs = (a: number, fa: number): boolean => {
235+
let ok = true;
236+
for (const b of g[a]) {
237+
if (b !== fa) {
238+
const t = dfs(b, a);
239+
ok = ok && t && colors[a] === colors[b];
240+
size[a] += size[b];
241+
}
242+
}
243+
if (ok) {
244+
ans = Math.max(ans, size[a]);
245+
}
246+
return ok;
247+
};
248+
dfs(0, -1);
249+
return ans;
250+
}
251+
```
252+
253+
### **...**
254+
255+
```
256+
257+
```
258+
259+
<!-- tabs:end -->

0 commit comments

Comments
 (0)