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 2754375

Browse files
feat: add solutions to lc problems: No.1245,3203 (doocs#3203)
* No.1245.Tree Diameter * No.3203.Find Minimum Diameter After Merging Two Trees
1 parent 4bd6a33 commit 2754375

File tree

26 files changed

+847
-351
lines changed

26 files changed

+847
-351
lines changed

‎solution/0100-0199/0128.Longest Consecutive Sequence/README.md‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ tags:
2020

2121
<p>给定一个未排序的整数数组 <code>nums</code> ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。</p>
2222

23-
<p>请你设计并实现时间复杂度为<code>O(n)</code><em> </em>的算法解决此问题。</p>
23+
<p>请你设计并实现时间复杂度为&nbsp;<code>O(n)</code><em> </em>的算法解决此问题。</p>
2424

25-
<p></p>
25+
<p>&nbsp;</p>
2626

2727
<p><strong>示例 1:</strong></p>
2828

2929
<pre>
3030
<strong>输入:</strong>nums = [100,4,200,1,3,2]
3131
<strong>输出:</strong>4
32-
<strong>解释:</strong>最长数字连续序列是 <code>[1, 2, 3, 4]。它的长度为 4。</code></pre>
32+
<strong>解释:</strong>最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。</pre>
3333

3434
<p><strong>示例 2:</strong></p>
3535

@@ -38,13 +38,13 @@ tags:
3838
<strong>输出:</strong>9
3939
</pre>
4040

41-
<p></p>
41+
<p>&nbsp;</p>
4242

4343
<p><strong>提示:</strong></p>
4444

4545
<ul>
46-
<li><code>0 <= nums.length <= 10<sup>5</sup></code></li>
47-
<li><code>-10<sup>9</sup> <= nums[i] <= 10<sup>9</sup></code></li>
46+
<li><code>0 &lt;= nums.length &lt;= 10<sup>5</sup></code></li>
47+
<li><code>-10<sup>9</sup> &lt;= nums[i] &lt;= 10<sup>9</sup></code></li>
4848
</ul>
4949

5050
<!-- description:end -->

‎solution/0200-0299/0262.Trips and Users/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ tags:
2929
| driver_id | int |
3030
| city_id | int |
3131
| status | enum |
32-
| request_at | date |
32+
| request_at | varchar |
3333
+-------------+----------+
3434
id 是这张表的主键(具有唯一值的列)。
3535
这张表中存所有出租车的行程信息。每段行程有唯一 id ,其中 client_id 和 driver_id 是 Users 表中 users_id 的外键。

‎solution/0200-0299/0262.Trips and Users/README_EN.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ tags:
2727
| driver_id | int |
2828
| city_id | int |
2929
| status | enum |
30-
| request_at | date |
30+
| request_at | varchar |
3131
+-------------+----------+
3232
id is the primary key (column with unique values) for this table.
3333
The table holds all taxi trips. Each trip has a unique id, while client_id and driver_id are foreign keys to the users_id at the Users table.

‎solution/1000-1099/1084.Sales Analysis III/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ product_id 是 Product 表的外键(reference 列)。
5050

5151
<p>&nbsp;</p>
5252

53-
<p>编写解决方案,报告<code>2019年春季</code>才售出的产品。即<strong>仅</strong>在<code><strong>2019年01月01日</strong></code><code><strong>2019年03月31日</strong></code>(含)之间出售的商品。</p>
53+
<p>编写解决方案,报告&nbsp;<code>2019年春季</code>&nbsp;才售出的产品。即&nbsp;<strong>仅&nbsp;</strong>在&nbsp;<code><strong>2019年01月01日</strong></code><strong>&nbsp;</strong>(含)至&nbsp;<code><strong>2019年03月31日</strong></code><strong>&nbsp;</strong>(含)之间出售的商品。</p>
5454

5555
<p>以 <strong>任意顺序</strong> 返回结果表。</p>
5656

‎solution/1200-1299/1245.Tree Diameter/README.md‎

Lines changed: 97 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -69,21 +69,9 @@ tags:
6969

7070
### 方法一:两次 DFS
7171

72-
首先对任意一个结点做 DFS 求出最远的结点,然后以这个结点为根结点再做 DFS 到达另一个最远结点。第一次 DFS 到达的结点可以证明一定是这个图的直径的一端,第二次 DFS 就会达到另一端。下面来证明这个定理
72+
我们首先任选一个节点,从该节点开始进行深度优先搜索,找到距离该节点最远的节点,记为节点 $a$。然后从节点 $a$ 开始进行深度优先搜索,找到距离节点 $a$ 最远的节点,记为节点 $b$。可以证明,节点 $a$ 和节点 $b$ 之间的路径即为树的直径
7373

74-
定理:在一个连通无向无环图中,以任意结点出发所能到达的最远结点,一定是该图直径的端点之一。
75-
76-
证明:假设这条直径是 δ(s, t)。分两种情况:
77-
78-
1. 当出发结点 y 在 δ(s, t) 时,假设到达的最远结点 z 不是 s, t 中的任一个。这时将 δ(y, z) 与不与之重合的 δ(y, s) 拼接(也可以假设不与之重合的是直径的另一个方向),可以得到一条更长的直径,与前提矛盾。
79-
1. 当出发结点 y 不在 δ(s, t) 上时,分两种情况:
80-
81-
- 当 y 到达的最远结点 z 横穿 δ(s, t) 时,记与之相交的结点为 x。此时有 δ(y, z) = δ(y, x) + δ(x, z)。而此时 δ(y, z) > δ(y, t),故可得 δ(x, z) > δ(x, t)。由 1 的结论可知该假设不成立。
82-
- 当 y 到达的最远结点 z 与 δ(s, t) 不相交时,定义从 y 开始到 t 结束的简单路径上,第一个同时也存在于简单路径 δ(s, t) 上的结点为 x,最后一个存在于简单路径 δ(y, z) 上的结点为 x’。如下图。那么根据假设,有 δ(y, z) ≥ δ(y, t) => δ(x', z) ≥ δ(x', x) + δ(x, t)。既然这样,那么 δ(x, z) ≥ δ(x, t),和 δ(s, t) 对应着直径这一前提不符,故 y 的最远结点 z 不可能在 s 到 t 这个直径对应的路外面。
83-
84-
<img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/1200-1299/1245.Tree%20Diameter/images/tree-diameter.svg">
85-
86-
因此定理成立。
74+
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 为节点数。
8775

8876
相似题目:
8977

@@ -96,66 +84,56 @@ tags:
9684
```python
9785
class Solution:
9886
def treeDiameter(self, edges: List[List[int]]) -> int:
99-
def dfs(u, t):
100-
nonlocal ans, vis, d, next
101-
if vis[u]:
102-
return
103-
vis[u] = True
104-
for v in d[u]:
105-
dfs(v, t + 1)
87+
def dfs(i: int, fa: int, t: int):
88+
for j in g[i]:
89+
if j != fa:
90+
dfs(j, i, t + 1)
91+
nonlocal ans, a
10692
if ans < t:
10793
ans = t
108-
next = u
109-
110-
d = defaultdict(set)
111-
vis = [False] * (len(edges) + 1)
112-
for u, v in edges:
113-
d[u].add(v)
114-
d[v].add(u)
115-
ans = 0
116-
next = 0
117-
dfs(edges[0][0], 0)
118-
vis = [False] * (len(edges) + 1)
119-
dfs(next, 0)
94+
a = i
95+
96+
g = defaultdict(list)
97+
for a, b in edges:
98+
g[a].append(b)
99+
g[b].append(a)
100+
ans = a = 0
101+
dfs(0, -1, 0)
102+
dfs(a, -1, 0)
120103
return ans
121104
```
122105

123106
#### Java
124107

125108
```java
126109
class Solution {
127-
private Map<Integer, Set<Integer>> g;
128-
private boolean[] vis;
129-
private int next;
110+
private List<Integer>[] g;
130111
private int ans;
112+
private int a;
131113

132114
public int treeDiameter(int[][] edges) {
133-
int n = edges.length;
134-
ans = 0;
135-
g = new HashMap<>();
136-
for (int[] e : edges) {
137-
g.computeIfAbsent(e[0], k -> new HashSet<>()).add(e[1]);
138-
g.computeIfAbsent(e[1], k -> new HashSet<>()).add(e[0]);
115+
int n = edges.length + 1;
116+
g = new List[n];
117+
Arrays.setAll(g, k -> new ArrayList<>());
118+
for (var e : edges) {
119+
int a = e[0], b = e[1];
120+
g[a].add(b);
121+
g[b].add(a);
139122
}
140-
vis = new boolean[n + 1];
141-
next = edges[0][0];
142-
dfs(next, 0);
143-
vis = new boolean[n + 1];
144-
dfs(next, 0);
123+
dfs(0, -1, 0);
124+
dfs(a, -1, 0);
145125
return ans;
146126
}
147127

148-
private void dfs(int u, int t) {
149-
if (vis[u]) {
150-
return;
128+
private void dfs(int i, int fa, int t) {
129+
for (int j : g[i]) {
130+
if (j != fa) {
131+
dfs(j, i, t + 1);
132+
}
151133
}
152-
vis[u] = true;
153134
if (ans < t) {
154135
ans = t;
155-
next = u;
156-
}
157-
for (int v : g.get(u)) {
158-
dfs(v, t + 1);
136+
a = i;
159137
}
160138
}
161139
}
@@ -166,71 +144,88 @@ class Solution {
166144
```cpp
167145
class Solution {
168146
public:
169-
unordered_map<int, unordered_set<int>> g;
170-
vector<bool> vis;
171-
int ans;
172-
int next;
173-
174147
int treeDiameter(vector<vector<int>>& edges) {
148+
int n = edges.size() + 1;
149+
vector<int> g[n];
175150
for (auto& e : edges) {
176-
g[e[0]].insert(e[1]);
177-
g[e[1]].insert(e[0]);
151+
int a = e[0], b = e[1];
152+
g[a].push_back(b);
153+
g[b].push_back(a);
178154
}
179-
int n = edges.size();
180-
ans = 0;
181-
vis.resize(n + 1);
182-
next = edges[0][0];
183-
dfs(next, 0);
184-
vis.assign(vis.size(), false);
185-
dfs(next, 0);
155+
int ans = 0, a = 0;
156+
auto dfs = [&](auto&& dfs, int i, int fa, int t) -> void {
157+
for (int j : g[i]) {
158+
if (j != fa) {
159+
dfs(dfs, j, i, t + 1);
160+
}
161+
}
162+
if (ans < t) {
163+
ans = t;
164+
a = i;
165+
}
166+
};
167+
dfs(dfs, 0, -1, 0);
168+
dfs(dfs, a, -1, 0);
186169
return ans;
187170
}
188-
189-
void dfs(int u, int t) {
190-
if (vis[u]) return;
191-
vis[u] = true;
192-
if (ans < t) {
193-
ans = t;
194-
next = u;
195-
}
196-
for (int v : g[u]) dfs(v, t + 1);
197-
}
198171
};
199172
```
200173
201174
#### Go
202175
203176
```go
204-
func treeDiameter(edges [][]int) int {
205-
n := len(edges)
206-
g := make(map[int][]int)
177+
func treeDiameter(edges [][]int) (ans int) {
178+
n := len(edges) + 1
179+
g := make([][]int, n)
207180
for _, e := range edges {
208-
g[e[0]] = append(g[e[0]], e[1])
209-
g[e[1]] = append(g[e[1]], e[0])
181+
a, b := e[0], e[1]
182+
g[a] = append(g[a], b)
183+
g[b] = append(g[b], a)
210184
}
211-
vis := make(map[int]bool, n+1)
212-
ans := 0
213-
next := edges[0][0]
214-
var dfs func(u, t int)
215-
dfs = func(u, t int) {
216-
if vis[u] {
217-
return
185+
a := 0
186+
var dfs func(i, fa, t int)
187+
dfs = func(i, fa, t int) {
188+
for _, j := range g[i] {
189+
if j != fa {
190+
dfs(j, i, t+1)
191+
}
218192
}
219-
vis[u] = true
220193
if ans < t {
221194
ans = t
222-
next = u
223-
}
224-
if vs, ok := g[u]; ok {
225-
for _, v := range vs {
226-
dfs(v, t+1)
227-
}
195+
a = i
228196
}
229197
}
230-
dfs(next, 0)
231-
vis = make(map[int]bool, n+1)
232-
dfs(next, 0)
233-
return ans
198+
dfs(0, -1, 0)
199+
dfs(a, -1, 0)
200+
return
201+
}
202+
```
203+
204+
#### TypeScript
205+
206+
```ts
207+
function treeDiameter(edges: number[][]): number {
208+
const n = edges.length + 1;
209+
const g: number[][] = Array.from({ length: n }, () => []);
210+
for (const [a, b] of edges) {
211+
g[a].push(b);
212+
g[b].push(a);
213+
}
214+
let [ans, a] = [0, 0];
215+
const dfs = (i: number, fa: number, t: number): void => {
216+
for (const j of g[i]) {
217+
if (j !== fa) {
218+
dfs(j, i, t + 1);
219+
}
220+
}
221+
if (ans < t) {
222+
ans = t;
223+
a = i;
224+
}
225+
};
226+
dfs(0, -1, 0);
227+
dfs(a, -1, 0);
228+
return ans;
234229
}
235230
```
236231

0 commit comments

Comments
(0)

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