Skip to content

Commit a70577b

Browse files
authored
feat: add solutions to lc problem: No.310 (#2451)
No.0310.Minimum Height Trees
1 parent 76308b0 commit a70577b

File tree

7 files changed

+179
-44
lines changed

7 files changed

+179
-44
lines changed

solution/0300-0399/0310.Minimum Height Trees/README.md

+63-15
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@
5151

5252
## 解法
5353

54-
### 方法一
54+
### 方法一:拓扑排序
55+
56+
如果这棵树只有一个节点,那么这个节点就是最小高度树的根节点,直接返回这个节点即可。
57+
58+
如果这棵树有多个节点,那么一定存在叶子节点。叶子节点是只有一个相邻节点的节点。我们可以利用拓扑排序,从外向内剥离叶子节点,当我们到达最后一层的时候,剩下的节点就是最小高度树的根节点。
59+
60+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为节点数。
5561

5662
<!-- tabs:start -->
5763

@@ -60,7 +66,7 @@ class Solution:
6066
def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
6167
if n == 1:
6268
return [0]
63-
g = defaultdict(list)
69+
g = [[] for _ in range(n)]
6470
degree = [0] * n
6571
for a, b in edges:
6672
g[a].append(b)
@@ -85,7 +91,7 @@ class Solution:
8591
class Solution {
8692
public List<Integer> findMinHeightTrees(int n, int[][] edges) {
8793
if (n == 1) {
88-
return Collections.singletonList(0);
94+
return List.of(0);
8995
}
9096
List<Integer>[] g = new List[n];
9197
Arrays.setAll(g, k -> new ArrayList<>());
@@ -97,7 +103,7 @@ class Solution {
97103
++degree[a];
98104
++degree[b];
99105
}
100-
Queue<Integer> q = new LinkedList<>();
106+
Deque<Integer> q = new ArrayDeque<>();
101107
for (int i = 0; i < n; ++i) {
102108
if (degree[i] == 1) {
103109
q.offer(i);
@@ -125,7 +131,9 @@ class Solution {
125131
class Solution {
126132
public:
127133
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
128-
if (n == 1) return {0};
134+
if (n == 1) {
135+
return {0};
136+
}
129137
vector<vector<int>> g(n);
130138
vector<int> degree(n);
131139
for (auto& e : edges) {
@@ -136,19 +144,23 @@ public:
136144
++degree[b];
137145
}
138146
queue<int> q;
139-
for (int i = 0; i < n; ++i)
140-
if (degree[i] == 1)
147+
for (int i = 0; i < n; ++i) {
148+
if (degree[i] == 1) {
141149
q.push(i);
150+
}
151+
}
142152
vector<int> ans;
143153
while (!q.empty()) {
144154
ans.clear();
145155
for (int i = q.size(); i > 0; --i) {
146156
int a = q.front();
147157
q.pop();
148158
ans.push_back(a);
149-
for (int b : g[a])
150-
if (--degree[b] == 1)
159+
for (int b : g[a]) {
160+
if (--degree[b] == 1) {
151161
q.push(b);
162+
}
163+
}
152164
}
153165
}
154166
return ans;
@@ -157,7 +169,7 @@ public:
157169
```
158170
159171
```go
160-
func findMinHeightTrees(n int, edges [][]int) []int {
172+
func findMinHeightTrees(n int, edges [][]int) (ans []int) {
161173
if n == 1 {
162174
return []int{0}
163175
}
@@ -170,13 +182,12 @@ func findMinHeightTrees(n int, edges [][]int) []int {
170182
degree[a]++
171183
degree[b]++
172184
}
173-
var q []int
174-
for i := 0; i < n; i++ {
175-
if degree[i] == 1 {
185+
q := []int{}
186+
for i, d := range degree {
187+
if d == 1 {
176188
q = append(q, i)
177189
}
178190
}
179-
var ans []int
180191
for len(q) > 0 {
181192
ans = []int{}
182193
for i := len(q); i > 0; i-- {
@@ -191,7 +202,44 @@ func findMinHeightTrees(n int, edges [][]int) []int {
191202
}
192203
}
193204
}
194-
return ans
205+
return
206+
}
207+
```
208+
209+
```ts
210+
function findMinHeightTrees(n: number, edges: number[][]): number[] {
211+
if (n === 1) {
212+
return [0];
213+
}
214+
const g: number[][] = Array.from({ length: n }, () => []);
215+
const degree: number[] = Array(n).fill(0);
216+
for (const [a, b] of edges) {
217+
g[a].push(b);
218+
g[b].push(a);
219+
++degree[a];
220+
++degree[b];
221+
}
222+
const q: number[] = [];
223+
for (let i = 0; i < n; ++i) {
224+
if (degree[i] === 1) {
225+
q.push(i);
226+
}
227+
}
228+
const ans: number[] = [];
229+
while (q.length > 0) {
230+
ans.length = 0;
231+
const t: number[] = [];
232+
for (const a of q) {
233+
ans.push(a);
234+
for (const b of g[a]) {
235+
if (--degree[b] === 1) {
236+
t.push(b);
237+
}
238+
}
239+
}
240+
q.splice(0, q.length, ...t);
241+
}
242+
return ans;
195243
}
196244
```
197245

solution/0300-0399/0310.Minimum Height Trees/README_EN.md

+63-15
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@
4444

4545
## Solutions
4646

47-
### Solution 1
47+
### Solution 1: Topological Sorting
48+
49+
If the tree only has one node, then this node is the root of the minimum height tree. We can directly return this node.
50+
51+
If the tree has multiple nodes, there must be leaf nodes. A leaf node is a node that only has one adjacent node. We can use topological sorting to peel off the leaf nodes from the outside to the inside. When we reach the last layer, the remaining nodes are the root nodes of the minimum height tree.
52+
53+
The time complexity is $O(n)$ and the space complexity is $O(n)$, where $n$ is the number of nodes.
4854

4955
<!-- tabs:start -->
5056

@@ -53,7 +59,7 @@ class Solution:
5359
def findMinHeightTrees(self, n: int, edges: List[List[int]]) -> List[int]:
5460
if n == 1:
5561
return [0]
56-
g = defaultdict(list)
62+
g = [[] for _ in range(n)]
5763
degree = [0] * n
5864
for a, b in edges:
5965
g[a].append(b)
@@ -78,7 +84,7 @@ class Solution:
7884
class Solution {
7985
public List<Integer> findMinHeightTrees(int n, int[][] edges) {
8086
if (n == 1) {
81-
return Collections.singletonList(0);
87+
return List.of(0);
8288
}
8389
List<Integer>[] g = new List[n];
8490
Arrays.setAll(g, k -> new ArrayList<>());
@@ -90,7 +96,7 @@ class Solution {
9096
++degree[a];
9197
++degree[b];
9298
}
93-
Queue<Integer> q = new LinkedList<>();
99+
Deque<Integer> q = new ArrayDeque<>();
94100
for (int i = 0; i < n; ++i) {
95101
if (degree[i] == 1) {
96102
q.offer(i);
@@ -118,7 +124,9 @@ class Solution {
118124
class Solution {
119125
public:
120126
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
121-
if (n == 1) return {0};
127+
if (n == 1) {
128+
return {0};
129+
}
122130
vector<vector<int>> g(n);
123131
vector<int> degree(n);
124132
for (auto& e : edges) {
@@ -129,19 +137,23 @@ public:
129137
++degree[b];
130138
}
131139
queue<int> q;
132-
for (int i = 0; i < n; ++i)
133-
if (degree[i] == 1)
140+
for (int i = 0; i < n; ++i) {
141+
if (degree[i] == 1) {
134142
q.push(i);
143+
}
144+
}
135145
vector<int> ans;
136146
while (!q.empty()) {
137147
ans.clear();
138148
for (int i = q.size(); i > 0; --i) {
139149
int a = q.front();
140150
q.pop();
141151
ans.push_back(a);
142-
for (int b : g[a])
143-
if (--degree[b] == 1)
152+
for (int b : g[a]) {
153+
if (--degree[b] == 1) {
144154
q.push(b);
155+
}
156+
}
145157
}
146158
}
147159
return ans;
@@ -150,7 +162,7 @@ public:
150162
```
151163
152164
```go
153-
func findMinHeightTrees(n int, edges [][]int) []int {
165+
func findMinHeightTrees(n int, edges [][]int) (ans []int) {
154166
if n == 1 {
155167
return []int{0}
156168
}
@@ -163,13 +175,12 @@ func findMinHeightTrees(n int, edges [][]int) []int {
163175
degree[a]++
164176
degree[b]++
165177
}
166-
var q []int
167-
for i := 0; i < n; i++ {
168-
if degree[i] == 1 {
178+
q := []int{}
179+
for i, d := range degree {
180+
if d == 1 {
169181
q = append(q, i)
170182
}
171183
}
172-
var ans []int
173184
for len(q) > 0 {
174185
ans = []int{}
175186
for i := len(q); i > 0; i-- {
@@ -184,7 +195,44 @@ func findMinHeightTrees(n int, edges [][]int) []int {
184195
}
185196
}
186197
}
187-
return ans
198+
return
199+
}
200+
```
201+
202+
```ts
203+
function findMinHeightTrees(n: number, edges: number[][]): number[] {
204+
if (n === 1) {
205+
return [0];
206+
}
207+
const g: number[][] = Array.from({ length: n }, () => []);
208+
const degree: number[] = Array(n).fill(0);
209+
for (const [a, b] of edges) {
210+
g[a].push(b);
211+
g[b].push(a);
212+
++degree[a];
213+
++degree[b];
214+
}
215+
const q: number[] = [];
216+
for (let i = 0; i < n; ++i) {
217+
if (degree[i] === 1) {
218+
q.push(i);
219+
}
220+
}
221+
const ans: number[] = [];
222+
while (q.length > 0) {
223+
ans.length = 0;
224+
const t: number[] = [];
225+
for (const a of q) {
226+
ans.push(a);
227+
for (const b of g[a]) {
228+
if (--degree[b] === 1) {
229+
t.push(b);
230+
}
231+
}
232+
}
233+
q.splice(0, q.length, ...t);
234+
}
235+
return ans;
188236
}
189237
```
190238

solution/0300-0399/0310.Minimum Height Trees/Solution.cpp

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
class Solution {
22
public:
33
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
4-
if (n == 1) return {0};
4+
if (n == 1) {
5+
return {0};
6+
}
57
vector<vector<int>> g(n);
68
vector<int> degree(n);
79
for (auto& e : edges) {
@@ -12,19 +14,23 @@ class Solution {
1214
++degree[b];
1315
}
1416
queue<int> q;
15-
for (int i = 0; i < n; ++i)
16-
if (degree[i] == 1)
17+
for (int i = 0; i < n; ++i) {
18+
if (degree[i] == 1) {
1719
q.push(i);
20+
}
21+
}
1822
vector<int> ans;
1923
while (!q.empty()) {
2024
ans.clear();
2125
for (int i = q.size(); i > 0; --i) {
2226
int a = q.front();
2327
q.pop();
2428
ans.push_back(a);
25-
for (int b : g[a])
26-
if (--degree[b] == 1)
29+
for (int b : g[a]) {
30+
if (--degree[b] == 1) {
2731
q.push(b);
32+
}
33+
}
2834
}
2935
}
3036
return ans;

solution/0300-0399/0310.Minimum Height Trees/Solution.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
func findMinHeightTrees(n int, edges [][]int) []int {
1+
func findMinHeightTrees(n int, edges [][]int) (ans []int) {
22
if n == 1 {
33
return []int{0}
44
}
@@ -11,13 +11,12 @@ func findMinHeightTrees(n int, edges [][]int) []int {
1111
degree[a]++
1212
degree[b]++
1313
}
14-
var q []int
15-
for i := 0; i < n; i++ {
16-
if degree[i] == 1 {
14+
q := []int{}
15+
for i, d := range degree {
16+
if d == 1 {
1717
q = append(q, i)
1818
}
1919
}
20-
var ans []int
2120
for len(q) > 0 {
2221
ans = []int{}
2322
for i := len(q); i > 0; i-- {
@@ -32,5 +31,5 @@ func findMinHeightTrees(n int, edges [][]int) []int {
3231
}
3332
}
3433
}
35-
return ans
34+
return
3635
}

solution/0300-0399/0310.Minimum Height Trees/Solution.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
class Solution {
22
public List<Integer> findMinHeightTrees(int n, int[][] edges) {
33
if (n == 1) {
4-
return Collections.singletonList(0);
4+
return List.of(0);
55
}
66
List<Integer>[] g = new List[n];
77
Arrays.setAll(g, k -> new ArrayList<>());
@@ -13,7 +13,7 @@ public List<Integer> findMinHeightTrees(int n, int[][] edges) {
1313
++degree[a];
1414
++degree[b];
1515
}
16-
Queue<Integer> q = new LinkedList<>();
16+
Deque<Integer> q = new ArrayDeque<>();
1717
for (int i = 0; i < n; ++i) {
1818
if (degree[i] == 1) {
1919
q.offer(i);

0 commit comments

Comments
 (0)