diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/README.md b/solution/0100-0199/0128.Longest Consecutive Sequence/README.md
index 56b5db7e564f2..c760e4fe2d4fc 100644
--- a/solution/0100-0199/0128.Longest Consecutive Sequence/README.md
+++ b/solution/0100-0199/0128.Longest Consecutive Sequence/README.md
@@ -20,16 +20,16 @@ tags:
给定一个未排序的整数数组 nums
,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
-请你设计并实现时间复杂度为 O(n)
的算法解决此问题。
+请你设计并实现时间复杂度为 O(n)
的算法解决此问题。
-
+
示例 1:
输入:nums = [100,4,200,1,3,2]
输出:4
-解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
+解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
示例 2:
@@ -38,13 +38,13 @@ tags:
输出:9
-
+
提示:
- 0 <= nums.length <= 105
- -109 <= nums[i] <= 109
+ 0 <= nums.length <= 105
+ -109 <= nums[i] <= 109
diff --git a/solution/0200-0299/0262.Trips and Users/README.md b/solution/0200-0299/0262.Trips and Users/README.md
index e888c1cfeef50..f05d69f26414e 100644
--- a/solution/0200-0299/0262.Trips and Users/README.md
+++ b/solution/0200-0299/0262.Trips and Users/README.md
@@ -29,7 +29,7 @@ tags:
| driver_id | int |
| city_id | int |
| status | enum |
-| request_at | date |
+| request_at | varchar |
+-------------+----------+
id 是这张表的主键(具有唯一值的列)。
这张表中存所有出租车的行程信息。每段行程有唯一 id ,其中 client_id 和 driver_id 是 Users 表中 users_id 的外键。
diff --git a/solution/0200-0299/0262.Trips and Users/README_EN.md b/solution/0200-0299/0262.Trips and Users/README_EN.md
index 11be7ae0283dc..9a6ba0f585bbb 100644
--- a/solution/0200-0299/0262.Trips and Users/README_EN.md
+++ b/solution/0200-0299/0262.Trips and Users/README_EN.md
@@ -27,7 +27,7 @@ tags:
| driver_id | int |
| city_id | int |
| status | enum |
-| request_at | date |
+| request_at | varchar |
+-------------+----------+
id is the primary key (column with unique values) for this table.
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.
diff --git a/solution/1000-1099/1084.Sales Analysis III/README.md b/solution/1000-1099/1084.Sales Analysis III/README.md
index 14402238d8f8b..6517c7f2a2135 100644
--- a/solution/1000-1099/1084.Sales Analysis III/README.md
+++ b/solution/1000-1099/1084.Sales Analysis III/README.md
@@ -50,7 +50,7 @@ product_id 是 Product 表的外键(reference 列)。
-编写解决方案,报告2019年春季
才售出的产品。即仅在2019-01-01
至2019-03-31
(含)之间出售的商品。
+编写解决方案,报告 2019年春季
才售出的产品。即 仅 在 2019-01-01
(含)至 2019-03-31
(含)之间出售的商品。
以 任意顺序 返回结果表。
diff --git a/solution/1200-1299/1245.Tree Diameter/README.md b/solution/1200-1299/1245.Tree Diameter/README.md
index d2971481de5b8..9882aaf214732 100644
--- a/solution/1200-1299/1245.Tree Diameter/README.md
+++ b/solution/1200-1299/1245.Tree Diameter/README.md
@@ -69,21 +69,9 @@ tags:
### 方法一:两次 DFS
-首先对任意一个结点做 DFS 求出最远的结点,然后以这个结点为根结点再做 DFS 到达另一个最远结点。第一次 DFS 到达的结点可以证明一定是这个图的直径的一端,第二次 DFS 就会达到另一端。下面来证明这个定理。
+我们首先任选一个节点,从该节点开始进行深度优先搜索,找到距离该节点最远的节点,记为节点 $a$。然后从节点 $a$ 开始进行深度优先搜索,找到距离节点 $a$ 最远的节点,记为节点 $b$。可以证明,节点 $a$ 和节点 $b$ 之间的路径即为树的直径。
-定理:在一个连通无向无环图中,以任意结点出发所能到达的最远结点,一定是该图直径的端点之一。
-
-证明:假设这条直径是 δ(s, t)。分两种情况:
-
-1. 当出发结点 y 在 δ(s, t) 时,假设到达的最远结点 z 不是 s, t 中的任一个。这时将 δ(y, z) 与不与之重合的 δ(y, s) 拼接(也可以假设不与之重合的是直径的另一个方向),可以得到一条更长的直径,与前提矛盾。
-1. 当出发结点 y 不在 δ(s, t) 上时,分两种情况:
-
- - 当 y 到达的最远结点 z 横穿 δ(s, t) 时,记与之相交的结点为 x。此时有 δ(y, z) = δ(y, x) + δ(x, z)。而此时 δ(y, z) > δ(y, t),故可得 δ(x, z) > δ(x, t)。由 1 的结论可知该假设不成立。
- - 当 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 这个直径对应的路外面。
-
-
-
-因此定理成立。
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为节点数。
相似题目:
@@ -96,27 +84,22 @@ tags:
```python
class Solution:
def treeDiameter(self, edges: List[List[int]]) -> int:
- def dfs(u, t):
- nonlocal ans, vis, d, next
- if vis[u]:
- return
- vis[u] = True
- for v in d[u]:
- dfs(v, t + 1)
+ def dfs(i: int, fa: int, t: int):
+ for j in g[i]:
+ if j != fa:
+ dfs(j, i, t + 1)
+ nonlocal ans, a
if ans < t:
ans = t
- next = u
-
- d = defaultdict(set)
- vis = [False] * (len(edges) + 1)
- for u, v in edges:
- d[u].add(v)
- d[v].add(u)
- ans = 0
- next = 0
- dfs(edges[0][0], 0)
- vis = [False] * (len(edges) + 1)
- dfs(next, 0)
+ a = i
+
+ g = defaultdict(list)
+ for a, b in edges:
+ g[a].append(b)
+ g[b].append(a)
+ ans = a = 0
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
return ans
```
@@ -124,38 +107,33 @@ class Solution:
```java
class Solution {
- private Map> g;
- private boolean[] vis;
- private int next;
+ private List[] g;
private int ans;
+ private int a;
public int treeDiameter(int[][] edges) {
- int n = edges.length;
- ans = 0;
- g = new HashMap<>();
- for (int[] e : edges) {
- g.computeIfAbsent(e[0], k -> new HashSet<>()).add(e[1]);
- g.computeIfAbsent(e[1], k -> new HashSet<>()).add(e[0]);
+ int n = edges.length + 1;
+ g = new List[n];
+ Arrays.setAll(g, k -> new ArrayList<>());
+ for (var e : edges) {
+ int a = e[0], b = e[1];
+ g[a].add(b);
+ g[b].add(a);
}
- vis = new boolean[n + 1];
- next = edges[0][0];
- dfs(next, 0);
- vis = new boolean[n + 1];
- dfs(next, 0);
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
return ans;
}
- private void dfs(int u, int t) {
- if (vis[u]) {
- return;
+ private void dfs(int i, int fa, int t) {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(j, i, t + 1);
+ }
}
- vis[u] = true;
if (ans < t) {
ans = t;
- next = u;
- }
- for (int v : g.get(u)) {
- dfs(v, t + 1);
+ a = i;
}
}
}
@@ -166,71 +144,88 @@ class Solution {
```cpp
class Solution {
public:
- unordered_map> g;
- vector vis;
- int ans;
- int next;
-
int treeDiameter(vector>& edges) {
+ int n = edges.size() + 1;
+ vector g[n];
for (auto& e : edges) {
- g[e[0]].insert(e[1]);
- g[e[1]].insert(e[0]);
+ int a = e[0], b = e[1];
+ g[a].push_back(b);
+ g[b].push_back(a);
}
- int n = edges.size();
- ans = 0;
- vis.resize(n + 1);
- next = edges[0][0];
- dfs(next, 0);
- vis.assign(vis.size(), false);
- dfs(next, 0);
+ int ans = 0, a = 0;
+ auto dfs = [&](auto&& dfs, int i, int fa, int t) -> void {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(dfs, j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(dfs, 0, -1, 0);
+ dfs(dfs, a, -1, 0);
return ans;
}
-
- void dfs(int u, int t) {
- if (vis[u]) return;
- vis[u] = true;
- if (ans < t) {
- ans = t;
- next = u;
- }
- for (int v : g[u]) dfs(v, t + 1);
- }
};
```
#### Go
```go
-func treeDiameter(edges [][]int) int {
- n := len(edges)
- g := make(map[int][]int)
+func treeDiameter(edges [][]int) (ans int) {
+ n := len(edges) + 1
+ g := make([][]int, n)
for _, e := range edges {
- g[e[0]] = append(g[e[0]], e[1])
- g[e[1]] = append(g[e[1]], e[0])
+ a, b := e[0], e[1]
+ g[a] = append(g[a], b)
+ g[b] = append(g[b], a)
}
- vis := make(map[int]bool, n+1)
- ans := 0
- next := edges[0][0]
- var dfs func(u, t int)
- dfs = func(u, t int) {
- if vis[u] {
- return
+ a := 0
+ var dfs func(i, fa, t int)
+ dfs = func(i, fa, t int) {
+ for _, j := range g[i] {
+ if j != fa {
+ dfs(j, i, t+1)
+ }
}
- vis[u] = true
if ans < t {
ans = t
- next = u
- }
- if vs, ok := g[u]; ok {
- for _, v := range vs {
- dfs(v, t+1)
- }
+ a = i
}
}
- dfs(next, 0)
- vis = make(map[int]bool, n+1)
- dfs(next, 0)
- return ans
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function treeDiameter(edges: number[][]): number {
+ const n = edges.length + 1;
+ const g: number[][] = Array.from({ length: n }, () => []);
+ for (const [a, b] of edges) {
+ g[a].push(b);
+ g[b].push(a);
+ }
+ let [ans, a] = [0, 0];
+ const dfs = (i: number, fa: number, t: number): void => {
+ for (const j of g[i]) {
+ if (j !== fa) {
+ dfs(j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
+ return ans;
}
```
diff --git a/solution/1200-1299/1245.Tree Diameter/README_EN.md b/solution/1200-1299/1245.Tree Diameter/README_EN.md
index 0b35f34886d88..1c468310a4631 100644
--- a/solution/1200-1299/1245.Tree Diameter/README_EN.md
+++ b/solution/1200-1299/1245.Tree Diameter/README_EN.md
@@ -61,27 +61,15 @@ tags:
-### Solution 1: Two DFS
+### Solution 1: Two DFS Passes
-First, perform DFS on any node to find the furthest node, then perform DFS again from this node to reach another furthest node. The node reached by the first DFS can be proven to be one end of the diameter of this graph, and the second DFS will reach the other end. Let's prove this theorem.
+First, we arbitrarily select a node and start a depth-first search (DFS) from this node to find the farthest node from it, denoted as node $a$. Then, we start another DFS from node $a$ to find the farthest node from node $a$, denoted as node $b$. It can be proven that the path between node $a$ and node $b$ is the diameter of the tree.
-Theorem: In a connected undirected acyclic graph, the furthest node that can be reached from any node must be one end of the diameter of the graph.
-
-Proof: Suppose this diameter is $\delta(s, t)$. There are two cases:
-
-1. When the starting node $y$ is on $\delta(s, t)$, suppose the furthest node $z$ reached is not any of $s, t$. At this time, connect $\delta(y, z)$ with $\delta(y, s)$ that does not overlap with it (you can also assume that the other direction of the diameter does not overlap), you can get a longer diameter, which contradicts the premise.
-1. When the starting node $y$ is not on $\delta(s, t)$, there are two cases:
-
- - When the furthest node $z$ reached by $y$ crosses $\delta(s, t)$, mark the intersecting node as $x$. At this time, $\delta(y, z) = \delta(y, x) + \delta(x, z)$. And at this time $\delta(y, z) > \delta(y, t)$, so $\delta(x, z) > \delta(x, t)$. According to the conclusion of 1, this assumption is not established.
- - When the furthest node $z$ reached by $y$ does not intersect with $\delta(s, t)$, define the first node on the simple path from $y$ to $t$ that also exists on the simple path $\delta(s, t)$ as $x$, and the last node on the simple path $\delta(y, z)$ as $x'$. As shown in the figure below. Then according to the assumption, $\delta(y, z) \geq \delta(y, t) \Rightarrow \delta(x', z) \geq \delta(x', x) + \delta(x, t)$. In this case, $\delta(x, z) \geq \delta(x, t)$, which does not match the premise that $\delta(s, t)$ corresponds to the diameter, so the furthest node $z$ of $y$ cannot be outside the path corresponding to the diameter from $s$ to $t$.
-
-
-
-Therefore, the theorem holds.
+Time complexity is $O(n)$, and space complexity is $O(n)$, where $n$ is the number of nodes.
Similar problems:
-- [1522. Diameter of N-Ary Tree](https://github.com/doocs/leetcode/blob/main/solution/1500-1599/1522.Diameter%20of%20N-Ary%20Tree/README.md)
+- [1522. Diameter of N-Ary Tree 🔒](https://github.com/doocs/leetcode/blob/main/solution/1500-1599/1522.Diameter%20of%20N-Ary%20Tree/README_EN.md)
@@ -90,27 +78,22 @@ Similar problems:
```python
class Solution:
def treeDiameter(self, edges: List[List[int]]) -> int:
- def dfs(u, t):
- nonlocal ans, vis, d, next
- if vis[u]:
- return
- vis[u] = True
- for v in d[u]:
- dfs(v, t + 1)
+ def dfs(i: int, fa: int, t: int):
+ for j in g[i]:
+ if j != fa:
+ dfs(j, i, t + 1)
+ nonlocal ans, a
if ans < t:
ans = t
- next = u
-
- d = defaultdict(set)
- vis = [False] * (len(edges) + 1)
- for u, v in edges:
- d[u].add(v)
- d[v].add(u)
- ans = 0
- next = 0
- dfs(edges[0][0], 0)
- vis = [False] * (len(edges) + 1)
- dfs(next, 0)
+ a = i
+
+ g = defaultdict(list)
+ for a, b in edges:
+ g[a].append(b)
+ g[b].append(a)
+ ans = a = 0
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
return ans
```
@@ -118,38 +101,33 @@ class Solution:
```java
class Solution {
- private Map> g;
- private boolean[] vis;
- private int next;
+ private List[] g;
private int ans;
+ private int a;
public int treeDiameter(int[][] edges) {
- int n = edges.length;
- ans = 0;
- g = new HashMap<>();
- for (int[] e : edges) {
- g.computeIfAbsent(e[0], k -> new HashSet<>()).add(e[1]);
- g.computeIfAbsent(e[1], k -> new HashSet<>()).add(e[0]);
+ int n = edges.length + 1;
+ g = new List[n];
+ Arrays.setAll(g, k -> new ArrayList<>());
+ for (var e : edges) {
+ int a = e[0], b = e[1];
+ g[a].add(b);
+ g[b].add(a);
}
- vis = new boolean[n + 1];
- next = edges[0][0];
- dfs(next, 0);
- vis = new boolean[n + 1];
- dfs(next, 0);
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
return ans;
}
- private void dfs(int u, int t) {
- if (vis[u]) {
- return;
+ private void dfs(int i, int fa, int t) {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(j, i, t + 1);
+ }
}
- vis[u] = true;
if (ans < t) {
ans = t;
- next = u;
- }
- for (int v : g.get(u)) {
- dfs(v, t + 1);
+ a = i;
}
}
}
@@ -160,71 +138,88 @@ class Solution {
```cpp
class Solution {
public:
- unordered_map> g;
- vector vis;
- int ans;
- int next;
-
int treeDiameter(vector>& edges) {
+ int n = edges.size() + 1;
+ vector g[n];
for (auto& e : edges) {
- g[e[0]].insert(e[1]);
- g[e[1]].insert(e[0]);
+ int a = e[0], b = e[1];
+ g[a].push_back(b);
+ g[b].push_back(a);
}
- int n = edges.size();
- ans = 0;
- vis.resize(n + 1);
- next = edges[0][0];
- dfs(next, 0);
- vis.assign(vis.size(), false);
- dfs(next, 0);
+ int ans = 0, a = 0;
+ auto dfs = [&](auto&& dfs, int i, int fa, int t) -> void {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(dfs, j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(dfs, 0, -1, 0);
+ dfs(dfs, a, -1, 0);
return ans;
}
-
- void dfs(int u, int t) {
- if (vis[u]) return;
- vis[u] = true;
- if (ans < t) {
- ans = t;
- next = u;
- }
- for (int v : g[u]) dfs(v, t + 1);
- }
};
```
#### Go
```go
-func treeDiameter(edges [][]int) int {
- n := len(edges)
- g := make(map[int][]int)
+func treeDiameter(edges [][]int) (ans int) {
+ n := len(edges) + 1
+ g := make([][]int, n)
for _, e := range edges {
- g[e[0]] = append(g[e[0]], e[1])
- g[e[1]] = append(g[e[1]], e[0])
+ a, b := e[0], e[1]
+ g[a] = append(g[a], b)
+ g[b] = append(g[b], a)
}
- vis := make(map[int]bool, n+1)
- ans := 0
- next := edges[0][0]
- var dfs func(u, t int)
- dfs = func(u, t int) {
- if vis[u] {
- return
+ a := 0
+ var dfs func(i, fa, t int)
+ dfs = func(i, fa, t int) {
+ for _, j := range g[i] {
+ if j != fa {
+ dfs(j, i, t+1)
+ }
}
- vis[u] = true
if ans < t {
ans = t
- next = u
- }
- if vs, ok := g[u]; ok {
- for _, v := range vs {
- dfs(v, t+1)
- }
+ a = i
}
}
- dfs(next, 0)
- vis = make(map[int]bool, n+1)
- dfs(next, 0)
- return ans
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function treeDiameter(edges: number[][]): number {
+ const n = edges.length + 1;
+ const g: number[][] = Array.from({ length: n }, () => []);
+ for (const [a, b] of edges) {
+ g[a].push(b);
+ g[b].push(a);
+ }
+ let [ans, a] = [0, 0];
+ const dfs = (i: number, fa: number, t: number): void => {
+ for (const j of g[i]) {
+ if (j !== fa) {
+ dfs(j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
+ return ans;
}
```
diff --git a/solution/1200-1299/1245.Tree Diameter/Solution.cpp b/solution/1200-1299/1245.Tree Diameter/Solution.cpp
index d7e0d367b8103..800f0604accc4 100644
--- a/solution/1200-1299/1245.Tree Diameter/Solution.cpp
+++ b/solution/1200-1299/1245.Tree Diameter/Solution.cpp
@@ -1,32 +1,27 @@
class Solution {
public:
- unordered_map> g;
- vector vis;
- int ans;
- int next;
-
int treeDiameter(vector>& edges) {
+ int n = edges.size() + 1;
+ vector g[n];
for (auto& e : edges) {
- g[e[0]].insert(e[1]);
- g[e[1]].insert(e[0]);
+ int a = e[0], b = e[1];
+ g[a].push_back(b);
+ g[b].push_back(a);
}
- int n = edges.size();
- ans = 0;
- vis.resize(n + 1);
- next = edges[0][0];
- dfs(next, 0);
- vis.assign(vis.size(), false);
- dfs(next, 0);
+ int ans = 0, a = 0;
+ auto dfs = [&](auto&& dfs, int i, int fa, int t) -> void {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(dfs, j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(dfs, 0, -1, 0);
+ dfs(dfs, a, -1, 0);
return ans;
}
-
- void dfs(int u, int t) {
- if (vis[u]) return;
- vis[u] = true;
- if (ans < t) {
- ans = t;
- next = u;
- }
- for (int v : g[u]) dfs(v, t + 1);
- }
};
\ No newline at end of file
diff --git a/solution/1200-1299/1245.Tree Diameter/Solution.go b/solution/1200-1299/1245.Tree Diameter/Solution.go
index 511ec76bee197..487e7279c55cd 100644
--- a/solution/1200-1299/1245.Tree Diameter/Solution.go
+++ b/solution/1200-1299/1245.Tree Diameter/Solution.go
@@ -1,31 +1,25 @@
-func treeDiameter(edges [][]int) int {
- n := len(edges)
- g := make(map[int][]int)
+func treeDiameter(edges [][]int) (ans int) {
+ n := len(edges) + 1
+ g := make([][]int, n)
for _, e := range edges {
- g[e[0]] = append(g[e[0]], e[1])
- g[e[1]] = append(g[e[1]], e[0])
+ a, b := e[0], e[1]
+ g[a] = append(g[a], b)
+ g[b] = append(g[b], a)
}
- vis := make(map[int]bool, n+1)
- ans := 0
- next := edges[0][0]
- var dfs func(u, t int)
- dfs = func(u, t int) {
- if vis[u] {
- return
+ a := 0
+ var dfs func(i, fa, t int)
+ dfs = func(i, fa, t int) {
+ for _, j := range g[i] {
+ if j != fa {
+ dfs(j, i, t+1)
+ }
}
- vis[u] = true
if ans < t {
ans = t
- next = u
- }
- if vs, ok := g[u]; ok {
- for _, v := range vs {
- dfs(v, t+1)
- }
+ a = i
}
}
- dfs(next, 0)
- vis = make(map[int]bool, n+1)
- dfs(next, 0)
- return ans
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
+ return
}
\ No newline at end of file
diff --git a/solution/1200-1299/1245.Tree Diameter/Solution.java b/solution/1200-1299/1245.Tree Diameter/Solution.java
index 88744f35dafa0..d97d17cac2d84 100644
--- a/solution/1200-1299/1245.Tree Diameter/Solution.java
+++ b/solution/1200-1299/1245.Tree Diameter/Solution.java
@@ -1,36 +1,31 @@
class Solution {
- private Map> g;
- private boolean[] vis;
- private int next;
+ private List[] g;
private int ans;
+ private int a;
public int treeDiameter(int[][] edges) {
- int n = edges.length;
- ans = 0;
- g = new HashMap<>();
- for (int[] e : edges) {
- g.computeIfAbsent(e[0], k -> new HashSet<>()).add(e[1]);
- g.computeIfAbsent(e[1], k -> new HashSet<>()).add(e[0]);
+ int n = edges.length + 1;
+ g = new List[n];
+ Arrays.setAll(g, k -> new ArrayList<>());
+ for (var e : edges) {
+ int a = e[0], b = e[1];
+ g[a].add(b);
+ g[b].add(a);
}
- vis = new boolean[n + 1];
- next = edges[0][0];
- dfs(next, 0);
- vis = new boolean[n + 1];
- dfs(next, 0);
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
return ans;
}
- private void dfs(int u, int t) {
- if (vis[u]) {
- return;
+ private void dfs(int i, int fa, int t) {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(j, i, t + 1);
+ }
}
- vis[u] = true;
if (ans < t) {
ans = t;
- next = u;
- }
- for (int v : g.get(u)) {
- dfs(v, t + 1);
+ a = i;
}
}
}
\ No newline at end of file
diff --git a/solution/1200-1299/1245.Tree Diameter/Solution.py b/solution/1200-1299/1245.Tree Diameter/Solution.py
index fa8e030697e5c..b18dd3a4b36c9 100644
--- a/solution/1200-1299/1245.Tree Diameter/Solution.py
+++ b/solution/1200-1299/1245.Tree Diameter/Solution.py
@@ -1,24 +1,19 @@
class Solution:
def treeDiameter(self, edges: List[List[int]]) -> int:
- def dfs(u, t):
- nonlocal ans, vis, d, next
- if vis[u]:
- return
- vis[u] = True
- for v in d[u]:
- dfs(v, t + 1)
+ def dfs(i: int, fa: int, t: int):
+ for j in g[i]:
+ if j != fa:
+ dfs(j, i, t + 1)
+ nonlocal ans, a
if ans < t:
ans = t
- next = u
+ a = i
- d = defaultdict(set)
- vis = [False] * (len(edges) + 1)
- for u, v in edges:
- d[u].add(v)
- d[v].add(u)
- ans = 0
- next = 0
- dfs(edges[0][0], 0)
- vis = [False] * (len(edges) + 1)
- dfs(next, 0)
+ g = defaultdict(list)
+ for a, b in edges:
+ g[a].append(b)
+ g[b].append(a)
+ ans = a = 0
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
return ans
diff --git a/solution/1200-1299/1245.Tree Diameter/Solution.ts b/solution/1200-1299/1245.Tree Diameter/Solution.ts
new file mode 100644
index 0000000000000..b2a4dc037f481
--- /dev/null
+++ b/solution/1200-1299/1245.Tree Diameter/Solution.ts
@@ -0,0 +1,23 @@
+function treeDiameter(edges: number[][]): number {
+ const n = edges.length + 1;
+ const g: number[][] = Array.from({ length: n }, () => []);
+ for (const [a, b] of edges) {
+ g[a].push(b);
+ g[b].push(a);
+ }
+ let [ans, a] = [0, 0];
+ const dfs = (i: number, fa: number, t: number): void => {
+ for (const j of g[i]) {
+ if (j !== fa) {
+ dfs(j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
+ return ans;
+}
diff --git a/solution/2200-2299/2227.Encrypt and Decrypt Strings/README.md b/solution/2200-2299/2227.Encrypt and Decrypt Strings/README.md
index 2d6ebcfefa55b..6401e5a1cf2f7 100644
--- a/solution/2200-2299/2227.Encrypt and Decrypt Strings/README.md
+++ b/solution/2200-2299/2227.Encrypt and Decrypt Strings/README.md
@@ -31,6 +31,8 @@ tags:
在字符串中,用 values[i]
替换字符 c
。
+请注意,如果 keys
中不存在字符串中的字符,则无法执行加密过程,返回空字符串 ""
。
+
字符串 解密 按下述步骤进行:
diff --git a/solution/2700-2799/2712.Minimum Cost to Make All Characters Equal/README.md b/solution/2700-2799/2712.Minimum Cost to Make All Characters Equal/README.md
index a92082dcb53e7..744cd2e6fbaab 100644
--- a/solution/2700-2799/2712.Minimum Cost to Make All Characters Equal/README.md
+++ b/solution/2700-2799/2712.Minimum Cost to Make All Characters Equal/README.md
@@ -50,7 +50,7 @@ tags:
执行第一种操作,选中下标 i = 1 ,可以得到 s = "011101" ,成本为 2 。
执行第一种操作,选中下标 i = 0 ,可以得到 s = "111101" ,成本为 1 。
执行第二种操作,选中下标 i = 4 ,可以得到 s = "111110" ,成本为 2 。
-执行第一种操作,选中下标 i = 5 ,可以得到 s = "111111" ,成本为 1 。
+执行第二种操作,选中下标 i = 5 ,可以得到 s = "111111" ,成本为 1 。
使所有字符相等的总成本等于 9 。可以证明 9 是使所有字符相等的最小成本。
diff --git a/solution/3000-3099/3086.Minimum Moves to Pick K Ones/README.md b/solution/3000-3099/3086.Minimum Moves to Pick K Ones/README.md
index eda2a22ef5c65..e8f81d6682487 100644
--- a/solution/3000-3099/3086.Minimum Moves to Pick K Ones/README.md
+++ b/solution/3000-3099/3086.Minimum Moves to Pick K Ones/README.md
@@ -44,7 +44,7 @@ tags:
解释:如果游戏开始时 Alice 在 aliceIndex == 1
的位置上,按照以下步骤执行每个动作,他可以利用 3
次行动拾取 3
个 1 :
- - 游戏开始时 Alice 拾取了一个 1 ,
nums[1]
变成了 0
。此时 nums
变为 [1,1,1,0,0,1,1,0,0,1]
。
+ - 游戏开始时 Alice 拾取了一个 1 ,
nums[1]
变成了 0
。此时 nums
变为 [1,0,1,0,0,1,1,0,0,1]
。
- 选择
j == 2
并执行第一种类型的动作。nums
变为 [1,0,1,0,0,1,1,0,0,1]
- 选择
x == 2
和 y == 1
,并执行第二种类型的动作。nums
变为 [1,1,0,0,0,1,1,0,0,1]
。由于 y == aliceIndex
,Alice 拾取了一个 1 ,nums
变为 [1,0,0,0,0,1,1,0,0,1]
。
- 选择
x == 0
和 y == 1
,并执行第二种类型的动作。nums
变为 [0,1,0,0,0,1,1,0,0,1]
。由于 y == aliceIndex
,Alice 拾取了一个 1 ,nums
变为 [0,0,0,0,0,1,1,0,0,1]
。
diff --git a/solution/3000-3099/3086.Minimum Moves to Pick K Ones/README_EN.md b/solution/3000-3099/3086.Minimum Moves to Pick K Ones/README_EN.md
index 998d7e2119ee8..6ce12dd2b913d 100644
--- a/solution/3000-3099/3086.Minimum Moves to Pick K Ones/README_EN.md
+++ b/solution/3000-3099/3086.Minimum Moves to Pick K Ones/README_EN.md
@@ -43,10 +43,10 @@ tags:
Explanation: Alice can pick up 3
ones in 3
moves, if Alice performs the following actions in each move when standing at aliceIndex == 1
:
- - At the start of the game Alice picks up the one and
nums[1]
becomes 0
. nums
becomes [1,1,1,0,0,1,1,0,0,1]
.
+ - At the start of the game Alice picks up the one and
nums[1]
becomes 0
. nums
becomes [1,0,0,0,0,1,1,0,0,1]
.
- Select
j == 2
and perform an action of the first type. nums
becomes [1,0,1,0,0,1,1,0,0,1]
- - Select
x == 2
and y == 1
, and perform an action of the second type. nums
becomes [1,1,0,0,0,1,1,0,0,1]
. As y == aliceIndex
, Alice picks up the one and nums
becomes [1,0,0,0,0,1,1,0,0,1]
.
- - Select
x == 0
and y == 1
, and perform an action of the second type. nums
becomes [0,1,0,0,0,1,1,0,0,1]
. As y == aliceIndex
, Alice picks up the one and nums
becomes [0,0,0,0,0,1,1,0,0,1]
.
+ - Select
x == 2
and y == 1
, and perform an action of the second type. nums
becomes [1,1,0,0,0,1,1,0,0,1]
. As y == aliceIndex
, Alice picks up the one and nums
becomes [1,0,0,0,0,1,1,0,0,1]
.
+ - Select
x == 0
and y == 1
, and perform an action of the second type. nums
becomes [0,1,0,0,0,1,1,0,0,1]
. As y == aliceIndex
, Alice picks up the one and nums
becomes [0,0,0,0,0,1,1,0,0,1]
.
Note that it may be possible for Alice to pick up 3
ones using some other sequence of 3
moves.
@@ -63,9 +63,9 @@ tags:
- Select
j == 1
and perform an action of the first type. nums
becomes [0,1,0,0]
.
- - Select
x == 1
and y == 0
, and perform an action of the second type. nums
becomes [1,0,0,0]
. As y == aliceIndex
, Alice picks up the one and nums
becomes [0,0,0,0]
.
+ - Select
x == 1
and y == 0
, and perform an action of the second type. nums
becomes [1,0,0,0]
. As y == aliceIndex
, Alice picks up the one and nums
becomes [0,0,0,0]
.
- Select
j == 1
again and perform an action of the first type. nums
becomes [0,1,0,0]
.
- - Select
x == 1
and y == 0
again, and perform an action of the second type. nums
becomes [1,0,0,0]
. As y == aliceIndex
, Alice picks up the one and nums
becomes [0,0,0,0]
.
+ - Select
x == 1
and y == 0
again, and perform an action of the second type. nums
becomes [1,0,0,0]
. As y == aliceIndex
, Alice picks up the one and nums
becomes [0,0,0,0]
.
diff --git a/solution/3100-3199/3172.Second Day Verification/README_EN.md b/solution/3100-3199/3172.Second Day Verification/README_EN.md
index 2b4ccfb2f45b5..1600422038ff9 100644
--- a/solution/3100-3199/3172.Second Day Verification/README_EN.md
+++ b/solution/3100-3199/3172.Second Day Verification/README_EN.md
@@ -96,8 +96,8 @@ Each row of this table contains the text ID, email ID, signup action, and action
Explanation:
- - User with email_id 7005 signed up on 2022-08-20 10:00:00 and verified on second day of the signup.
- - User with email_id 7771 signed up on 2022-06-14 09:30:00 and verified on second day of the signup.
+ - User with user_id 7005 and email_id 234 signed up on 2022-08-20 10:00:00 and verified on second day of the signup.
+ - User with user_id 7771 and email_id 125 signed up on 2022-06-14 09:30:00 and verified on second day of the signup.
diff --git a/solution/3100-3199/3199.Count Triplets with Even XOR Set Bits I/README.md b/solution/3100-3199/3199.Count Triplets with Even XOR Set Bits I/README.md
index 34d390b223bb2..8a3a0e671b22e 100644
--- a/solution/3100-3199/3199.Count Triplets with Even XOR Set Bits I/README.md
+++ b/solution/3100-3199/3199.Count Triplets with Even XOR Set Bits I/README.md
@@ -9,7 +9,7 @@ tags:
-# [3199. Count Triplets with Even XOR Set Bits I 🔒](https://leetcode.cn/problems/count-triplets-with-even-xor-set-bits-i)
+# [3199. 用偶数异或设置位计数三元组 I 🔒](https://leetcode.cn/problems/count-triplets-with-even-xor-set-bits-i)
[English Version](/solution/3100-3199/3199.Count%20Triplets%20with%20Even%20XOR%20Set%20Bits%20I/README_EN.md)
@@ -17,31 +17,32 @@ tags:
-Given three integer arrays a
, b
, and c
, return the number of triplets (a[i], b[j], c[k])
, such that the bitwise XOR
of the elements of each triplet has an even number of set bits.
+给定三个整数数组 a
,b
和 c
,返回组内元素按位 XOR
有 偶数 个 设置位 的三元组 (a[i], b[j], c[k])
的数量。
-Example 1:
+
+示例 1:
-
Input: a = [1], b = [2], c = [3]
+
输入:a = [1], b = [2], c = [3]
-
Output: 1
+
输出:1
-
Explanation:
+
解释:
-
The only triplet is (a[0], b[0], c[0])
and their XOR
is: 1 XOR 2 XOR 3 = 002
.
+
只有一个三元组 (a[0], b[0], c[0])
并且它们的 XOR
为:1 XOR 2 XOR 3 = 002
。
-Example 2:
+示例 2:
-
Input: a = [1,1], b = [2,3], c = [1,5]
+
输入:a = [1,1], b = [2,3], c = [1,5]
-
Output: 4
+
输出:4
-
Explanation:
+
解释:
-
Consider these four triplets:
+
考虑以下 4 个三元组:
(a[0], b[1], c[0])
: 1 XOR 3 XOR 1 = 0112
@@ -52,7 +53,8 @@ Given three integer arrays a
, b
, and c
, r
-Constraints:
+
+提示:
1 <= a.length, b.length, c.length <= 100
diff --git a/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/README.md b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/README.md
index 7a69f88cf67a8..55ea8c8eb34f7 100644
--- a/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/README.md
+++ b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/README.md
@@ -75,32 +75,202 @@ tags:
-### 方法一
+### 方法一:两次 DFS
+
+我们记 $d_1$ 和 $d_2$ 分别为两棵树的直径,那么合并后的树的直径有以下两种情况:
+
+1. 合并后的树的直径为原始的一棵树的直径,即 $\max(d_1, d_2)$;
+2. 合并后的树的直径经过原始的两棵树。我们分别计算原始的两棵树的半径 $r_1 = \lceil \frac{d_1}{2} \rceil$ 和 $r_2 = \lceil \frac{d_2}{2} \rceil$,那么合并后的树的直径为 $r_1 + r_2 + 1$。
+
+我们取这两种情况的最大值即可。
+
+在计算树的直径时,我们可以使用两次 DFS。首先我们任选一点出发,找到距离该点最远的点,记为 $a$。然后从点 $a$ 出发,找到距离点 $a$ 最远的点,记为 $b$。可以证明,点 $a$ 和点 $b$ 之间的路径即为树的直径。
+
+时间复杂度 $O(n + m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别为两棵树的节点数。
#### Python3
```python
-
+class Solution:
+ def minimumDiameterAfterMerge(
+ self, edges1: List[List[int]], edges2: List[List[int]]
+ ) -> int:
+ d1 = self.treeDiameter(edges1)
+ d2 = self.treeDiameter(edges2)
+ return max(d1, d2, (d1 + 1) // 2 + (d2 + 1) // 2 + 1)
+
+ def treeDiameter(self, edges: List[List[int]]) -> int:
+ def dfs(i: int, fa: int, t: int):
+ for j in g[i]:
+ if j != fa:
+ dfs(j, i, t + 1)
+ nonlocal ans, a
+ if ans < t:
+ ans = t
+ a = i
+
+ g = defaultdict(list)
+ for a, b in edges:
+ g[a].append(b)
+ g[b].append(a)
+ ans = a = 0
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
+ return ans
```
#### Java
```java
-
+class Solution {
+ private List[] g;
+ private int ans;
+ private int a;
+
+ public int minimumDiameterAfterMerge(int[][] edges1, int[][] edges2) {
+ int d1 = treeDiameter(edges1);
+ int d2 = treeDiameter(edges2);
+ return Math.max(Math.max(d1, d2), (d1 + 1) / 2 + (d2 + 1) / 2 + 1);
+ }
+
+ public int treeDiameter(int[][] edges) {
+ int n = edges.length + 1;
+ g = new List[n];
+ Arrays.setAll(g, k -> new ArrayList<>());
+ ans = 0;
+ a = 0;
+ for (var e : edges) {
+ int a = e[0], b = e[1];
+ g[a].add(b);
+ g[b].add(a);
+ }
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
+ return ans;
+ }
+
+ private void dfs(int i, int fa, int t) {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ }
+}
```
#### C++
```cpp
-
+class Solution {
+public:
+ int minimumDiameterAfterMerge(vector>& edges1, vector>& edges2) {
+ int d1 = treeDiameter(edges1);
+ int d2 = treeDiameter(edges2);
+ return max({d1, d2, (d1 + 1) / 2 + (d2 + 1) / 2 + 1});
+ }
+
+ int treeDiameter(vector>& edges) {
+ int n = edges.size() + 1;
+ vector g[n];
+ for (auto& e : edges) {
+ int a = e[0], b = e[1];
+ g[a].push_back(b);
+ g[b].push_back(a);
+ }
+ int ans = 0, a = 0;
+ auto dfs = [&](auto&& dfs, int i, int fa, int t) -> void {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(dfs, j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(dfs, 0, -1, 0);
+ dfs(dfs, a, -1, 0);
+ return ans;
+ }
+};
```
#### Go
```go
+func minimumDiameterAfterMerge(edges1 [][]int, edges2 [][]int) int {
+ d1 := treeDiameter(edges1)
+ d2 := treeDiameter(edges2)
+ return max(max(d1, d2), (d1+1)/2+(d2+1)/2+1)
+}
+
+func treeDiameter(edges [][]int) (ans int) {
+ n := len(edges) + 1
+ g := make([][]int, n)
+ for _, e := range edges {
+ a, b := e[0], e[1]
+ g[a] = append(g[a], b)
+ g[b] = append(g[b], a)
+ }
+ a := 0
+ var dfs func(i, fa, t int)
+ dfs = func(i, fa, t int) {
+ for _, j := range g[i] {
+ if j != fa {
+ dfs(j, i, t+1)
+ }
+ }
+ if ans < t {
+ ans = t
+ a = i
+ }
+ }
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
+ return
+}
+```
+#### TypeScript
+
+```ts
+function minimumDiameterAfterMerge(edges1: number[][], edges2: number[][]): number {
+ const d1 = treeDiameter(edges1);
+ const d2 = treeDiameter(edges2);
+ return Math.max(d1, d2, Math.ceil(d1 / 2) + Math.ceil(d2 / 2) + 1);
+}
+
+function treeDiameter(edges: number[][]): number {
+ const n = edges.length + 1;
+ const g: number[][] = Array.from({ length: n }, () => []);
+ for (const [a, b] of edges) {
+ g[a].push(b);
+ g[b].push(a);
+ }
+ let [ans, a] = [0, 0];
+ const dfs = (i: number, fa: number, t: number): void => {
+ for (const j of g[i]) {
+ if (j !== fa) {
+ dfs(j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
+ return ans;
+}
```
diff --git a/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/README_EN.md b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/README_EN.md
index 2cb3f266d16db..9eae9c17028fd 100644
--- a/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/README_EN.md
+++ b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/README_EN.md
@@ -73,32 +73,202 @@ tags:
-### Solution 1
+### Solution 1: Two DFS Passes
+
+We denote $d_1$ and $d_2$ as the diameters of the two trees, respectively. Then, the diameter of the merged tree can be one of the following two cases:
+
+1. The diameter of the merged tree is the diameter of one of the original trees, i.e., $\max(d_1, d_2)$;
+2. The diameter of the merged tree passes through both of the original trees. We calculate the radii of the original two trees as $r_1 = \lceil \frac{d_1}{2} \rceil$ and $r_2 = \lceil \frac{d_2}{2} \rceil$, respectively. Then, the diameter of the merged tree is $r_1 + r_2 + 1$.
+
+We take the maximum of these two cases.
+
+When calculating the diameter of a tree, we can use two DFS passes. First, we arbitrarily select a node and start a DFS from this node to find the farthest node from it, denoted as node $a$. Then, we start another DFS from node $a$ to find the farthest node from node $a$, denoted as node $b$. It can be proven that the path between node $a$ and node $b$ is the diameter of the tree.
+
+The time complexity is $O(n + m)$, and the space complexity is $O(n + m)$, where $n$ and $m$ are the number of nodes in the two trees, respectively.
#### Python3
```python
-
+class Solution:
+ def minimumDiameterAfterMerge(
+ self, edges1: List[List[int]], edges2: List[List[int]]
+ ) -> int:
+ d1 = self.treeDiameter(edges1)
+ d2 = self.treeDiameter(edges2)
+ return max(d1, d2, (d1 + 1) // 2 + (d2 + 1) // 2 + 1)
+
+ def treeDiameter(self, edges: List[List[int]]) -> int:
+ def dfs(i: int, fa: int, t: int):
+ for j in g[i]:
+ if j != fa:
+ dfs(j, i, t + 1)
+ nonlocal ans, a
+ if ans < t:
+ ans = t
+ a = i
+
+ g = defaultdict(list)
+ for a, b in edges:
+ g[a].append(b)
+ g[b].append(a)
+ ans = a = 0
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
+ return ans
```
#### Java
```java
-
+class Solution {
+ private List[] g;
+ private int ans;
+ private int a;
+
+ public int minimumDiameterAfterMerge(int[][] edges1, int[][] edges2) {
+ int d1 = treeDiameter(edges1);
+ int d2 = treeDiameter(edges2);
+ return Math.max(Math.max(d1, d2), (d1 + 1) / 2 + (d2 + 1) / 2 + 1);
+ }
+
+ public int treeDiameter(int[][] edges) {
+ int n = edges.length + 1;
+ g = new List[n];
+ Arrays.setAll(g, k -> new ArrayList<>());
+ ans = 0;
+ a = 0;
+ for (var e : edges) {
+ int a = e[0], b = e[1];
+ g[a].add(b);
+ g[b].add(a);
+ }
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
+ return ans;
+ }
+
+ private void dfs(int i, int fa, int t) {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ }
+}
```
#### C++
```cpp
-
+class Solution {
+public:
+ int minimumDiameterAfterMerge(vector>& edges1, vector>& edges2) {
+ int d1 = treeDiameter(edges1);
+ int d2 = treeDiameter(edges2);
+ return max({d1, d2, (d1 + 1) / 2 + (d2 + 1) / 2 + 1});
+ }
+
+ int treeDiameter(vector>& edges) {
+ int n = edges.size() + 1;
+ vector g[n];
+ for (auto& e : edges) {
+ int a = e[0], b = e[1];
+ g[a].push_back(b);
+ g[b].push_back(a);
+ }
+ int ans = 0, a = 0;
+ auto dfs = [&](auto&& dfs, int i, int fa, int t) -> void {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(dfs, j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(dfs, 0, -1, 0);
+ dfs(dfs, a, -1, 0);
+ return ans;
+ }
+};
```
#### Go
```go
+func minimumDiameterAfterMerge(edges1 [][]int, edges2 [][]int) int {
+ d1 := treeDiameter(edges1)
+ d2 := treeDiameter(edges2)
+ return max(max(d1, d2), (d1+1)/2+(d2+1)/2+1)
+}
+
+func treeDiameter(edges [][]int) (ans int) {
+ n := len(edges) + 1
+ g := make([][]int, n)
+ for _, e := range edges {
+ a, b := e[0], e[1]
+ g[a] = append(g[a], b)
+ g[b] = append(g[b], a)
+ }
+ a := 0
+ var dfs func(i, fa, t int)
+ dfs = func(i, fa, t int) {
+ for _, j := range g[i] {
+ if j != fa {
+ dfs(j, i, t+1)
+ }
+ }
+ if ans < t {
+ ans = t
+ a = i
+ }
+ }
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
+ return
+}
+```
+#### TypeScript
+
+```ts
+function minimumDiameterAfterMerge(edges1: number[][], edges2: number[][]): number {
+ const d1 = treeDiameter(edges1);
+ const d2 = treeDiameter(edges2);
+ return Math.max(d1, d2, Math.ceil(d1 / 2) + Math.ceil(d2 / 2) + 1);
+}
+
+function treeDiameter(edges: number[][]): number {
+ const n = edges.length + 1;
+ const g: number[][] = Array.from({ length: n }, () => []);
+ for (const [a, b] of edges) {
+ g[a].push(b);
+ g[b].push(a);
+ }
+ let [ans, a] = [0, 0];
+ const dfs = (i: number, fa: number, t: number): void => {
+ for (const j of g[i]) {
+ if (j !== fa) {
+ dfs(j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
+ return ans;
+}
```
diff --git a/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.cpp b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.cpp
new file mode 100644
index 0000000000000..c8b1ca3566545
--- /dev/null
+++ b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.cpp
@@ -0,0 +1,33 @@
+class Solution {
+public:
+ int minimumDiameterAfterMerge(vector>& edges1, vector>& edges2) {
+ int d1 = treeDiameter(edges1);
+ int d2 = treeDiameter(edges2);
+ return max({d1, d2, (d1 + 1) / 2 + (d2 + 1) / 2 + 1});
+ }
+
+ int treeDiameter(vector>& edges) {
+ int n = edges.size() + 1;
+ vector g[n];
+ for (auto& e : edges) {
+ int a = e[0], b = e[1];
+ g[a].push_back(b);
+ g[b].push_back(a);
+ }
+ int ans = 0, a = 0;
+ auto dfs = [&](auto&& dfs, int i, int fa, int t) -> void {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(dfs, j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(dfs, 0, -1, 0);
+ dfs(dfs, a, -1, 0);
+ return ans;
+ }
+};
\ No newline at end of file
diff --git a/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.go b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.go
new file mode 100644
index 0000000000000..4ab6408b235ad
--- /dev/null
+++ b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.go
@@ -0,0 +1,31 @@
+func minimumDiameterAfterMerge(edges1 [][]int, edges2 [][]int) int {
+ d1 := treeDiameter(edges1)
+ d2 := treeDiameter(edges2)
+ return max(max(d1, d2), (d1+1)/2+(d2+1)/2+1)
+}
+
+func treeDiameter(edges [][]int) (ans int) {
+ n := len(edges) + 1
+ g := make([][]int, n)
+ for _, e := range edges {
+ a, b := e[0], e[1]
+ g[a] = append(g[a], b)
+ g[b] = append(g[b], a)
+ }
+ a := 0
+ var dfs func(i, fa, t int)
+ dfs = func(i, fa, t int) {
+ for _, j := range g[i] {
+ if j != fa {
+ dfs(j, i, t+1)
+ }
+ }
+ if ans < t {
+ ans = t
+ a = i
+ }
+ }
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
+ return
+}
\ No newline at end of file
diff --git a/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.java b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.java
new file mode 100644
index 0000000000000..a346bd4d4d743
--- /dev/null
+++ b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.java
@@ -0,0 +1,39 @@
+class Solution {
+ private List[] g;
+ private int ans;
+ private int a;
+
+ public int minimumDiameterAfterMerge(int[][] edges1, int[][] edges2) {
+ int d1 = treeDiameter(edges1);
+ int d2 = treeDiameter(edges2);
+ return Math.max(Math.max(d1, d2), (d1 + 1) / 2 + (d2 + 1) / 2 + 1);
+ }
+
+ public int treeDiameter(int[][] edges) {
+ int n = edges.length + 1;
+ g = new List[n];
+ Arrays.setAll(g, k -> new ArrayList<>());
+ ans = 0;
+ a = 0;
+ for (var e : edges) {
+ int a = e[0], b = e[1];
+ g[a].add(b);
+ g[b].add(a);
+ }
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
+ return ans;
+ }
+
+ private void dfs(int i, int fa, int t) {
+ for (int j : g[i]) {
+ if (j != fa) {
+ dfs(j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ }
+}
\ No newline at end of file
diff --git a/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.py b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.py
new file mode 100644
index 0000000000000..a9c12217da1d3
--- /dev/null
+++ b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.py
@@ -0,0 +1,26 @@
+class Solution:
+ def minimumDiameterAfterMerge(
+ self, edges1: List[List[int]], edges2: List[List[int]]
+ ) -> int:
+ d1 = self.treeDiameter(edges1)
+ d2 = self.treeDiameter(edges2)
+ return max(d1, d2, (d1 + 1) // 2 + (d2 + 1) // 2 + 1)
+
+ def treeDiameter(self, edges: List[List[int]]) -> int:
+ def dfs(i: int, fa: int, t: int):
+ for j in g[i]:
+ if j != fa:
+ dfs(j, i, t + 1)
+ nonlocal ans, a
+ if ans < t:
+ ans = t
+ a = i
+
+ g = defaultdict(list)
+ for a, b in edges:
+ g[a].append(b)
+ g[b].append(a)
+ ans = a = 0
+ dfs(0, -1, 0)
+ dfs(a, -1, 0)
+ return ans
diff --git a/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.ts b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.ts
new file mode 100644
index 0000000000000..6203c5afb4ec0
--- /dev/null
+++ b/solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.ts
@@ -0,0 +1,29 @@
+function minimumDiameterAfterMerge(edges1: number[][], edges2: number[][]): number {
+ const d1 = treeDiameter(edges1);
+ const d2 = treeDiameter(edges2);
+ return Math.max(d1, d2, Math.ceil(d1 / 2) + Math.ceil(d2 / 2) + 1);
+}
+
+function treeDiameter(edges: number[][]): number {
+ const n = edges.length + 1;
+ const g: number[][] = Array.from({ length: n }, () => []);
+ for (const [a, b] of edges) {
+ g[a].push(b);
+ g[b].push(a);
+ }
+ let [ans, a] = [0, 0];
+ const dfs = (i: number, fa: number, t: number): void => {
+ for (const j of g[i]) {
+ if (j !== fa) {
+ dfs(j, i, t + 1);
+ }
+ }
+ if (ans < t) {
+ ans = t;
+ a = i;
+ }
+ };
+ dfs(0, -1, 0);
+ dfs(a, -1, 0);
+ return ans;
+}
diff --git a/solution/3200-3299/3205.Maximum Array Hopping Score I/README.md b/solution/3200-3299/3205.Maximum Array Hopping Score I/README.md
index da3729f76276c..a48f4b0b2f2fd 100644
--- a/solution/3200-3299/3205.Maximum Array Hopping Score I/README.md
+++ b/solution/3200-3299/3205.Maximum Array Hopping Score I/README.md
@@ -6,7 +6,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3205.Ma
-# [3205. Maximum Array Hopping Score I 🔒](https://leetcode.cn/problems/maximum-array-hopping-score-i)
+# [3205. 最大数组跳跃得分 I 🔒](https://leetcode.cn/problems/maximum-array-hopping-score-i)
[English Version](/solution/3200-3299/3205.Maximum%20Array%20Hopping%20Score%20I/README_EN.md)
@@ -14,44 +14,46 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3205.Ma
-Given an array nums
, you have to get the maximum score starting from index 0 and hopping until you reach the last element of the array.
+给定一个数组 nums
,你必须从索引 0 开始跳跃,直到到达数组的最后一个元素,使得获取 最大 分数。
-In each hop, you can jump from index i
to an index j > i
, and you get a score of (j - i) * nums[j]
.
+每一次 跳跃 中,你可以从下标 i
跳到一个 j > i
的下标,并且可以得到 (j - i) * nums[j]
的分数。
-Return the maximum score you can get.
+返回你能够取得的最大分数。
-Example 1:
+
+示例 1:
-
Input: nums = [1,5,8]
+
输入:nums = [1,5,8]
-
Output: 16
+
输出:16
-
Explanation:
+
解释:
-
There are two possible ways to reach the last element:
+
有两种可能的方法可以到达最后一个元素:
- 0 -> 1 -> 2
with a score of (1 - 0) * 5 + (2 - 1) * 8 = 13
.
- 0 -> 2
with a score of (2 - 0) * 8 = 16
.
+ 0 -> 1 -> 2
得分为 (1 - 0) * 5 + (2 - 1) * 8 = 13
。
+ 0 -> 2
得分为 (2 - 0) * 8 = 16
。
-Example 2:
+示例 2:
-
Input: nums = [4,5,2,8,9,1,3]
+
输入:nums = [4,5,2,8,9,1,3]
-
Output: 42
+
输出:42
-
Explanation:
+
解释:
-
We can do the hopping 0 -> 4 -> 6
with a score of (4 - 0) * 9 + (6 - 4) * 3 = 42
.
+
我们可以按 0 -> 4 -> 6
进行跳跃,得分为 (4 - 0) * 9 + (6 - 4) * 3 = 42
。
-Constraints:
+
+提示:
2 <= nums.length <= 103
diff --git a/solution/README.md b/solution/README.md
index 7417457340a65..b36307d089567 100644
--- a/solution/README.md
+++ b/solution/README.md
@@ -3209,13 +3209,13 @@
| 3196 | [最大化子数组的总成本](/solution/3100-3199/3196.Maximize%20Total%20Cost%20of%20Alternating%20Subarrays/README.md) | `数组`,`动态规划` | 中等 | 第 403 场周赛 |
| 3197 | [包含所有 1 的最小矩形面积 II](/solution/3100-3199/3197.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20II/README.md) | `数组`,`枚举`,`矩阵` | 困难 | 第 403 场周赛 |
| 3198 | [查找每个州的城市](/solution/3100-3199/3198.Find%20Cities%20in%20Each%20State/README.md) | `数据库` | 简单 | 🔒 |
-| 3199 | [Count Triplets with Even XOR Set Bits I](/solution/3100-3199/3199.Count%20Triplets%20with%20Even%20XOR%20Set%20Bits%20I/README.md) | `位运算`,`数组` | 简单 | 🔒 |
+| 3199 | [用偶数异或设置位计数三元组 I](/solution/3100-3199/3199.Count%20Triplets%20with%20Even%20XOR%20Set%20Bits%20I/README.md) | `位运算`,`数组` | 简单 | 🔒 |
| 3200 | [三角形的最大高度](/solution/3200-3299/3200.Maximum%20Height%20of%20a%20Triangle/README.md) | `数组`,`枚举` | 简单 | 第 404 场周赛 |
| 3201 | [找出有效子序列的最大长度 I](/solution/3200-3299/3201.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20I/README.md) | `数组`,`动态规划` | 中等 | 第 404 场周赛 |
| 3202 | [找出有效子序列的最大长度 II](/solution/3200-3299/3202.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20II/README.md) | `数组`,`动态规划` | 中等 | 第 404 场周赛 |
| 3203 | [合并两棵树后的最小直径](/solution/3200-3299/3203.Find%20Minimum%20Diameter%20After%20Merging%20Two%20Trees/README.md) | `树`,`深度优先搜索`,`广度优先搜索`,`图` | 困难 | 第 404 场周赛 |
| 3204 | [按位用户权限分析](/solution/3200-3299/3204.Bitwise%20User%20Permissions%20Analysis/README.md) | `数据库` | 中等 | 🔒 |
-| 3205 | [Maximum Array Hopping Score I](/solution/3200-3299/3205.Maximum%20Array%20Hopping%20Score%20I/README.md) | | 中等 | 🔒 |
+| 3205 | [最大数组跳跃得分 I](/solution/3200-3299/3205.Maximum%20Array%20Hopping%20Score%20I/README.md) | | 中等 | 🔒 |
## 版权