From 35bbf7eb47cf6ab14b7f7564d0f067f558429c89 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Fri, 5 Jul 2024 09:53:17 +0800 Subject: [PATCH 1/3] feat: add solutions to lc problems: No.1245,3203 * No.1245.Tree Diameter * No.3203.Find Minimum Diameter After Merging Two Trees --- .../README.md | 12 +- .../0200-0299/0262.Trips and Users/README.md | 2 +- .../0262.Trips and Users/README_EN.md | 2 +- .../1084.Sales Analysis III/README.md | 2 +- .../1200-1299/1245.Tree Diameter/README.md | 199 +++++++++-------- .../1200-1299/1245.Tree Diameter/README_EN.md | 203 +++++++++--------- .../1200-1299/1245.Tree Diameter/Solution.cpp | 43 ++-- .../1200-1299/1245.Tree Diameter/Solution.go | 40 ++-- .../1245.Tree Diameter/Solution.java | 39 ++-- .../1200-1299/1245.Tree Diameter/Solution.py | 31 ++- .../1200-1299/1245.Tree Diameter/Solution.ts | 23 ++ .../README.md | 2 + .../README.md | 2 +- .../README_EN.md | 10 +- .../3172.Second Day Verification/README_EN.md | 4 +- .../README.md | 178 ++++++++++++++- .../README_EN.md | 178 ++++++++++++++- .../Solution.cpp | 33 +++ .../Solution.go | 31 +++ .../Solution.java | 39 ++++ .../Solution.py | 26 +++ .../Solution.ts | 29 +++ solution/CONTEST_README.md | 6 - solution/CONTEST_README_EN.md | 6 - solution/DATABASE_README.md | 2 - solution/DATABASE_README_EN.md | 2 - solution/README.md | 10 - solution/README_EN.md | 10 - 28 files changed, 810 insertions(+), 354 deletions(-) create mode 100644 solution/1200-1299/1245.Tree Diameter/Solution.ts create mode 100644 solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.cpp create mode 100644 solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.go create mode 100644 solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.java create mode 100644 solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.py create mode 100644 solution/3200-3299/3203.Find Minimum Diameter After Merging Two Trees/Solution.ts 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 -

 

+

 

提示:

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-012019-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_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/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/CONTEST_README.md b/solution/CONTEST_README.md index 79e2b9c975d58..901ed1a2fa7d5 100644 --- a/solution/CONTEST_README.md +++ b/solution/CONTEST_README.md @@ -28,17 +28,11 @@ comments: true #### 第 404 场周赛(2024-06-30 10:30, 90 分钟) 参赛人数 3485 -- [3200. 三角形的最大高度](/solution/3200-3299/3200.Maximum%20Height%20of%20a%20Triangle/README.md) -- [3201. 找出有效子序列的最大长度 I](/solution/3200-3299/3201.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20I/README.md) -- [3202. 找出有效子序列的最大长度 II](/solution/3200-3299/3202.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20II/README.md) -- [3203. 合并两棵树后的最小直径](/solution/3200-3299/3203.Find%20Minimum%20Diameter%20After%20Merging%20Two%20Trees/README.md) #### 第 403 场周赛(2024-06-23 10:30, 90 分钟) 参赛人数 3112 - [3194. 最小元素和最大元素的最小平均值](/solution/3100-3199/3194.Minimum%20Average%20of%20Smallest%20and%20Largest%20Elements/README.md) - [3195. 包含所有 1 的最小矩形面积 I](/solution/3100-3199/3195.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20I/README.md) -- [3196. 最大化子数组的总成本](/solution/3100-3199/3196.Maximize%20Total%20Cost%20of%20Alternating%20Subarrays/README.md) -- [3197. 包含所有 1 的最小矩形面积 II](/solution/3100-3199/3197.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20II/README.md) #### 第 133 场双周赛(2024-06-22 22:30, 90 分钟) 参赛人数 2326 diff --git a/solution/CONTEST_README_EN.md b/solution/CONTEST_README_EN.md index b123e0f8eb5f3..bf81f91f5ecde 100644 --- a/solution/CONTEST_README_EN.md +++ b/solution/CONTEST_README_EN.md @@ -31,17 +31,11 @@ If you want to estimate your score changes after the contest ends, you can visit #### Weekly Contest 404 -- [3200. Maximum Height of a Triangle](/solution/3200-3299/3200.Maximum%20Height%20of%20a%20Triangle/README_EN.md) -- [3201. Find the Maximum Length of Valid Subsequence I](/solution/3200-3299/3201.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20I/README_EN.md) -- [3202. Find the Maximum Length of Valid Subsequence II](/solution/3200-3299/3202.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20II/README_EN.md) -- [3203. Find Minimum Diameter After Merging Two Trees](/solution/3200-3299/3203.Find%20Minimum%20Diameter%20After%20Merging%20Two%20Trees/README_EN.md) #### Weekly Contest 403 - [3194. Minimum Average of Smallest and Largest Elements](/solution/3100-3199/3194.Minimum%20Average%20of%20Smallest%20and%20Largest%20Elements/README_EN.md) - [3195. Find the Minimum Area to Cover All Ones I](/solution/3100-3199/3195.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20I/README_EN.md) -- [3196. Maximize Total Cost of Alternating Subarrays](/solution/3100-3199/3196.Maximize%20Total%20Cost%20of%20Alternating%20Subarrays/README_EN.md) -- [3197. Find the Minimum Area to Cover All Ones II](/solution/3100-3199/3197.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20II/README_EN.md) #### Biweekly Contest 133 diff --git a/solution/DATABASE_README.md b/solution/DATABASE_README.md index 816a7fd10edf3..b5bedc16e6352 100644 --- a/solution/DATABASE_README.md +++ b/solution/DATABASE_README.md @@ -284,8 +284,6 @@ | 3172 | [第二天验证](/solution/3100-3199/3172.Second%20Day%20Verification/README.md) | `数据库` | 简单 | 🔒 | | 3182 | [查找得分最高的学生](/solution/3100-3199/3182.Find%20Top%20Scoring%20Students/README.md) | `数据库` | 中等 | 🔒 | | 3188 | [查找得分最高的学生 II](/solution/3100-3199/3188.Find%20Top%20Scoring%20Students%20II/README.md) | `数据库` | 困难 | 🔒 | -| 3198 | [查找每个州的城市](/solution/3100-3199/3198.Find%20Cities%20in%20Each%20State/README.md) | `数据库` | 简单 | 🔒 | -| 3204 | [按位用户权限分析](/solution/3200-3299/3204.Bitwise%20User%20Permissions%20Analysis/README.md) | `数据库` | 中等 | 🔒 | ## 版权 diff --git a/solution/DATABASE_README_EN.md b/solution/DATABASE_README_EN.md index 4b21c83adf29c..fdbb39ccdc638 100644 --- a/solution/DATABASE_README_EN.md +++ b/solution/DATABASE_README_EN.md @@ -282,8 +282,6 @@ Press Control + F(or Command + F on | 3172 | [Second Day Verification](/solution/3100-3199/3172.Second%20Day%20Verification/README_EN.md) | `Database` | Easy | 🔒 | | 3182 | [Find Top Scoring Students](/solution/3100-3199/3182.Find%20Top%20Scoring%20Students/README_EN.md) | `Database` | Medium | 🔒 | | 3188 | [Find Top Scoring Students II](/solution/3100-3199/3188.Find%20Top%20Scoring%20Students%20II/README_EN.md) | `Database` | Hard | 🔒 | -| 3198 | [Find Cities in Each State](/solution/3100-3199/3198.Find%20Cities%20in%20Each%20State/README_EN.md) | `Database` | Easy | 🔒 | -| 3204 | [Bitwise User Permissions Analysis](/solution/3200-3299/3204.Bitwise%20User%20Permissions%20Analysis/README_EN.md) | `Database` | Medium | 🔒 | ## Copyright diff --git a/solution/README.md b/solution/README.md index 7417457340a65..7e7f9efb58d70 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3206,16 +3206,6 @@ | 3193 | [统计逆序对的数目](/solution/3100-3199/3193.Count%20the%20Number%20of%20Inversions/README.md) | `数组`,`动态规划` | 困难 | 第 133 场双周赛 | | 3194 | [最小元素和最大元素的最小平均值](/solution/3100-3199/3194.Minimum%20Average%20of%20Smallest%20and%20Largest%20Elements/README.md) | `数组`,`双指针`,`排序` | 简单 | 第 403 场周赛 | | 3195 | [包含所有 1 的最小矩形面积 I](/solution/3100-3199/3195.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20I/README.md) | `数组`,`矩阵` | 中等 | 第 403 场周赛 | -| 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) | `位运算`,`数组` | 简单 | 🔒 | -| 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) | | 中等 | 🔒 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index 91a4e5e61a125..eb70d5590717c 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -3204,16 +3204,6 @@ Press Control + F(or Command + F on | 3193 | [Count the Number of Inversions](/solution/3100-3199/3193.Count%20the%20Number%20of%20Inversions/README_EN.md) | `Array`,`Dynamic Programming` | Hard | Biweekly Contest 133 | | 3194 | [Minimum Average of Smallest and Largest Elements](/solution/3100-3199/3194.Minimum%20Average%20of%20Smallest%20and%20Largest%20Elements/README_EN.md) | `Array`,`Two Pointers`,`Sorting` | Easy | Weekly Contest 403 | | 3195 | [Find the Minimum Area to Cover All Ones I](/solution/3100-3199/3195.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20I/README_EN.md) | `Array`,`Matrix` | Medium | Weekly Contest 403 | -| 3196 | [Maximize Total Cost of Alternating Subarrays](/solution/3100-3199/3196.Maximize%20Total%20Cost%20of%20Alternating%20Subarrays/README_EN.md) | `Array`,`Dynamic Programming` | Medium | Weekly Contest 403 | -| 3197 | [Find the Minimum Area to Cover All Ones II](/solution/3100-3199/3197.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20II/README_EN.md) | `Array`,`Enumeration`,`Matrix` | Hard | Weekly Contest 403 | -| 3198 | [Find Cities in Each State](/solution/3100-3199/3198.Find%20Cities%20in%20Each%20State/README_EN.md) | `Database` | Easy | 🔒 | -| 3199 | [Count Triplets with Even XOR Set Bits I](/solution/3100-3199/3199.Count%20Triplets%20with%20Even%20XOR%20Set%20Bits%20I/README_EN.md) | `Bit Manipulation`,`Array` | Easy | 🔒 | -| 3200 | [Maximum Height of a Triangle](/solution/3200-3299/3200.Maximum%20Height%20of%20a%20Triangle/README_EN.md) | `Array`,`Enumeration` | Easy | Weekly Contest 404 | -| 3201 | [Find the Maximum Length of Valid Subsequence I](/solution/3200-3299/3201.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20I/README_EN.md) | `Array`,`Dynamic Programming` | Medium | Weekly Contest 404 | -| 3202 | [Find the Maximum Length of Valid Subsequence II](/solution/3200-3299/3202.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20II/README_EN.md) | `Array`,`Dynamic Programming` | Medium | Weekly Contest 404 | -| 3203 | [Find Minimum Diameter After Merging Two Trees](/solution/3200-3299/3203.Find%20Minimum%20Diameter%20After%20Merging%20Two%20Trees/README_EN.md) | `Tree`,`Depth-First Search`,`Breadth-First Search`,`Graph` | Hard | Weekly Contest 404 | -| 3204 | [Bitwise User Permissions Analysis](/solution/3200-3299/3204.Bitwise%20User%20Permissions%20Analysis/README_EN.md) | `Database` | Medium | 🔒 | -| 3205 | [Maximum Array Hopping Score I](/solution/3200-3299/3205.Maximum%20Array%20Hopping%20Score%20I/README_EN.md) | | Medium | 🔒 | ## Copyright From 76a6aa64c877ad778aa902691a512acaa4dac97c Mon Sep 17 00:00:00 2001 From: yanglbme Date: Fri, 5 Jul 2024 10:04:34 +0800 Subject: [PATCH 2/3] feat: update --- .../README.md | 2 +- .../README.md | 28 ++++++++------- .../README.md | 36 ++++++++++--------- solution/CONTEST_README.md | 6 ++++ solution/CONTEST_README_EN.md | 6 ++++ solution/DATABASE_README.md | 2 ++ solution/DATABASE_README_EN.md | 2 ++ solution/README.md | 10 ++++++ solution/README_EN.md | 10 ++++++ solution/main.py | 2 +- 10 files changed, 72 insertions(+), 32 deletions(-) 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 == 2y == 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 == 0y == 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/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. +

        给定三个整数数组 ab 和 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/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/CONTEST_README.md b/solution/CONTEST_README.md index 901ed1a2fa7d5..79e2b9c975d58 100644 --- a/solution/CONTEST_README.md +++ b/solution/CONTEST_README.md @@ -28,11 +28,17 @@ comments: true #### 第 404 场周赛(2024-06-30 10:30, 90 分钟) 参赛人数 3485 +- [3200. 三角形的最大高度](/solution/3200-3299/3200.Maximum%20Height%20of%20a%20Triangle/README.md) +- [3201. 找出有效子序列的最大长度 I](/solution/3200-3299/3201.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20I/README.md) +- [3202. 找出有效子序列的最大长度 II](/solution/3200-3299/3202.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20II/README.md) +- [3203. 合并两棵树后的最小直径](/solution/3200-3299/3203.Find%20Minimum%20Diameter%20After%20Merging%20Two%20Trees/README.md) #### 第 403 场周赛(2024-06-23 10:30, 90 分钟) 参赛人数 3112 - [3194. 最小元素和最大元素的最小平均值](/solution/3100-3199/3194.Minimum%20Average%20of%20Smallest%20and%20Largest%20Elements/README.md) - [3195. 包含所有 1 的最小矩形面积 I](/solution/3100-3199/3195.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20I/README.md) +- [3196. 最大化子数组的总成本](/solution/3100-3199/3196.Maximize%20Total%20Cost%20of%20Alternating%20Subarrays/README.md) +- [3197. 包含所有 1 的最小矩形面积 II](/solution/3100-3199/3197.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20II/README.md) #### 第 133 场双周赛(2024-06-22 22:30, 90 分钟) 参赛人数 2326 diff --git a/solution/CONTEST_README_EN.md b/solution/CONTEST_README_EN.md index bf81f91f5ecde..b123e0f8eb5f3 100644 --- a/solution/CONTEST_README_EN.md +++ b/solution/CONTEST_README_EN.md @@ -31,11 +31,17 @@ If you want to estimate your score changes after the contest ends, you can visit #### Weekly Contest 404 +- [3200. Maximum Height of a Triangle](/solution/3200-3299/3200.Maximum%20Height%20of%20a%20Triangle/README_EN.md) +- [3201. Find the Maximum Length of Valid Subsequence I](/solution/3200-3299/3201.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20I/README_EN.md) +- [3202. Find the Maximum Length of Valid Subsequence II](/solution/3200-3299/3202.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20II/README_EN.md) +- [3203. Find Minimum Diameter After Merging Two Trees](/solution/3200-3299/3203.Find%20Minimum%20Diameter%20After%20Merging%20Two%20Trees/README_EN.md) #### Weekly Contest 403 - [3194. Minimum Average of Smallest and Largest Elements](/solution/3100-3199/3194.Minimum%20Average%20of%20Smallest%20and%20Largest%20Elements/README_EN.md) - [3195. Find the Minimum Area to Cover All Ones I](/solution/3100-3199/3195.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20I/README_EN.md) +- [3196. Maximize Total Cost of Alternating Subarrays](/solution/3100-3199/3196.Maximize%20Total%20Cost%20of%20Alternating%20Subarrays/README_EN.md) +- [3197. Find the Minimum Area to Cover All Ones II](/solution/3100-3199/3197.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20II/README_EN.md) #### Biweekly Contest 133 diff --git a/solution/DATABASE_README.md b/solution/DATABASE_README.md index b5bedc16e6352..816a7fd10edf3 100644 --- a/solution/DATABASE_README.md +++ b/solution/DATABASE_README.md @@ -284,6 +284,8 @@ | 3172 | [第二天验证](/solution/3100-3199/3172.Second%20Day%20Verification/README.md) | `数据库` | 简单 | 🔒 | | 3182 | [查找得分最高的学生](/solution/3100-3199/3182.Find%20Top%20Scoring%20Students/README.md) | `数据库` | 中等 | 🔒 | | 3188 | [查找得分最高的学生 II](/solution/3100-3199/3188.Find%20Top%20Scoring%20Students%20II/README.md) | `数据库` | 困难 | 🔒 | +| 3198 | [查找每个州的城市](/solution/3100-3199/3198.Find%20Cities%20in%20Each%20State/README.md) | `数据库` | 简单 | 🔒 | +| 3204 | [按位用户权限分析](/solution/3200-3299/3204.Bitwise%20User%20Permissions%20Analysis/README.md) | `数据库` | 中等 | 🔒 | ## 版权 diff --git a/solution/DATABASE_README_EN.md b/solution/DATABASE_README_EN.md index fdbb39ccdc638..4b21c83adf29c 100644 --- a/solution/DATABASE_README_EN.md +++ b/solution/DATABASE_README_EN.md @@ -282,6 +282,8 @@ Press Control + F(or Command + F on | 3172 | [Second Day Verification](/solution/3100-3199/3172.Second%20Day%20Verification/README_EN.md) | `Database` | Easy | 🔒 | | 3182 | [Find Top Scoring Students](/solution/3100-3199/3182.Find%20Top%20Scoring%20Students/README_EN.md) | `Database` | Medium | 🔒 | | 3188 | [Find Top Scoring Students II](/solution/3100-3199/3188.Find%20Top%20Scoring%20Students%20II/README_EN.md) | `Database` | Hard | 🔒 | +| 3198 | [Find Cities in Each State](/solution/3100-3199/3198.Find%20Cities%20in%20Each%20State/README_EN.md) | `Database` | Easy | 🔒 | +| 3204 | [Bitwise User Permissions Analysis](/solution/3200-3299/3204.Bitwise%20User%20Permissions%20Analysis/README_EN.md) | `Database` | Medium | 🔒 | ## Copyright diff --git a/solution/README.md b/solution/README.md index 7e7f9efb58d70..b36307d089567 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3206,6 +3206,16 @@ | 3193 | [统计逆序对的数目](/solution/3100-3199/3193.Count%20the%20Number%20of%20Inversions/README.md) | `数组`,`动态规划` | 困难 | 第 133 场双周赛 | | 3194 | [最小元素和最大元素的最小平均值](/solution/3100-3199/3194.Minimum%20Average%20of%20Smallest%20and%20Largest%20Elements/README.md) | `数组`,`双指针`,`排序` | 简单 | 第 403 场周赛 | | 3195 | [包含所有 1 的最小矩形面积 I](/solution/3100-3199/3195.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20I/README.md) | `数组`,`矩阵` | 中等 | 第 403 场周赛 | +| 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 | [用偶数异或设置位计数三元组 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 | [最大数组跳跃得分 I](/solution/3200-3299/3205.Maximum%20Array%20Hopping%20Score%20I/README.md) | | 中等 | 🔒 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index eb70d5590717c..91a4e5e61a125 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -3204,6 +3204,16 @@ Press Control + F(or Command + F on | 3193 | [Count the Number of Inversions](/solution/3100-3199/3193.Count%20the%20Number%20of%20Inversions/README_EN.md) | `Array`,`Dynamic Programming` | Hard | Biweekly Contest 133 | | 3194 | [Minimum Average of Smallest and Largest Elements](/solution/3100-3199/3194.Minimum%20Average%20of%20Smallest%20and%20Largest%20Elements/README_EN.md) | `Array`,`Two Pointers`,`Sorting` | Easy | Weekly Contest 403 | | 3195 | [Find the Minimum Area to Cover All Ones I](/solution/3100-3199/3195.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20I/README_EN.md) | `Array`,`Matrix` | Medium | Weekly Contest 403 | +| 3196 | [Maximize Total Cost of Alternating Subarrays](/solution/3100-3199/3196.Maximize%20Total%20Cost%20of%20Alternating%20Subarrays/README_EN.md) | `Array`,`Dynamic Programming` | Medium | Weekly Contest 403 | +| 3197 | [Find the Minimum Area to Cover All Ones II](/solution/3100-3199/3197.Find%20the%20Minimum%20Area%20to%20Cover%20All%20Ones%20II/README_EN.md) | `Array`,`Enumeration`,`Matrix` | Hard | Weekly Contest 403 | +| 3198 | [Find Cities in Each State](/solution/3100-3199/3198.Find%20Cities%20in%20Each%20State/README_EN.md) | `Database` | Easy | 🔒 | +| 3199 | [Count Triplets with Even XOR Set Bits I](/solution/3100-3199/3199.Count%20Triplets%20with%20Even%20XOR%20Set%20Bits%20I/README_EN.md) | `Bit Manipulation`,`Array` | Easy | 🔒 | +| 3200 | [Maximum Height of a Triangle](/solution/3200-3299/3200.Maximum%20Height%20of%20a%20Triangle/README_EN.md) | `Array`,`Enumeration` | Easy | Weekly Contest 404 | +| 3201 | [Find the Maximum Length of Valid Subsequence I](/solution/3200-3299/3201.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20I/README_EN.md) | `Array`,`Dynamic Programming` | Medium | Weekly Contest 404 | +| 3202 | [Find the Maximum Length of Valid Subsequence II](/solution/3200-3299/3202.Find%20the%20Maximum%20Length%20of%20Valid%20Subsequence%20II/README_EN.md) | `Array`,`Dynamic Programming` | Medium | Weekly Contest 404 | +| 3203 | [Find Minimum Diameter After Merging Two Trees](/solution/3200-3299/3203.Find%20Minimum%20Diameter%20After%20Merging%20Two%20Trees/README_EN.md) | `Tree`,`Depth-First Search`,`Breadth-First Search`,`Graph` | Hard | Weekly Contest 404 | +| 3204 | [Bitwise User Permissions Analysis](/solution/3200-3299/3204.Bitwise%20User%20Permissions%20Analysis/README_EN.md) | `Database` | Medium | 🔒 | +| 3205 | [Maximum Array Hopping Score I](/solution/3200-3299/3205.Maximum%20Array%20Hopping%20Score%20I/README_EN.md) | | Medium | 🔒 | ## Copyright diff --git a/solution/main.py b/solution/main.py index 0306fe83523ac..65c8fa4ff535e 100644 --- a/solution/main.py +++ b/solution/main.py @@ -446,7 +446,7 @@ def run(): except: slug = q["titleSlug"] qid = int(q["frontendQuestionId"]) - if slug in question_details: + if slug in question_details and qid < 3000: continue detail = spider.get_question_detail( slug, retry=4 From 82974d387041844de0527bf5c7fa4dac9949b9b1 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Fri, 5 Jul 2024 10:07:31 +0800 Subject: [PATCH 3/3] fix: update --- solution/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solution/main.py b/solution/main.py index 65c8fa4ff535e..0306fe83523ac 100644 --- a/solution/main.py +++ b/solution/main.py @@ -446,7 +446,7 @@ def run(): except: slug = q["titleSlug"] qid = int(q["frontendQuestionId"]) - if slug in question_details and qid < 3000: + if slug in question_details: continue detail = spider.get_question_detail( slug, retry=4