From d26fdb10ab898780582ced7830a08b59d4ec49cd Mon Sep 17 00:00:00 2001 From: yanglbme Date: Mon, 20 Jan 2025 17:24:58 +0800 Subject: [PATCH] feat: update solutions to lc problem: No.0547 No.0547.Number of Provinces --- .../0547.Number of Provinces/README.md | 17 +++++------ .../0547.Number of Provinces/README_EN.md | 29 ++++++++++++++----- .../0547.Number of Provinces/Solution.cpp | 4 +-- .../0547.Number of Provinces/Solution.ts | 2 +- .../0547.Number of Provinces/Solution2.cpp | 4 +-- .../0547.Number of Provinces/Solution2.ts | 5 +--- 6 files changed, 34 insertions(+), 27 deletions(-) diff --git a/solution/0500-0599/0547.Number of Provinces/README.md b/solution/0500-0599/0547.Number of Provinces/README.md index b386ad074240f..610c397f6bfa2 100644 --- a/solution/0500-0599/0547.Number of Provinces/README.md +++ b/solution/0500-0599/0547.Number of Provinces/README.md @@ -68,9 +68,9 @@ tags: ### 方法一:DFS -我们创建一个数组 $vis$,用于记录每个城市是否被访问过。 +我们创建一个数组 $\textit{vis}$,用于记录每个城市是否被访问过。 -接下来,遍历每个城市 $i$,如果该城市未被访问过,则从该城市开始深度优先搜索,通过矩阵 $isConnected$ 得到与该城市直接相连的城市有哪些,这些城市和该城市属于同一个省,然后对这些城市继续深度优先搜索,直到同一个省的所有城市都被访问到,即可得到一个省,将答案 $ans$ 加 $1$,然后遍历下一个未被访问过的城市,直到遍历完所有的城市。 +接下来,遍历每个城市 $i$,如果该城市未被访问过,则从该城市开始深度优先搜索,通过矩阵 $\textit{isConnected}$ 得到与该城市直接相连的城市有哪些,这些城市和该城市属于同一个省,然后对这些城市继续深度优先搜索,直到同一个省的所有城市都被访问到,即可得到一个省,将答案 $\textit{ans}$ 加 $1$,然后遍历下一个未被访问过的城市,直到遍历完所有的城市。 最后返回答案即可。 @@ -141,7 +141,7 @@ public: int ans = 0; bool vis[n]; memset(vis, false, sizeof(vis)); - function dfs = [&](int i) { + auto dfs = [&](this auto&& dfs, int i) -> void { vis[i] = true; for (int j = 0; j < n; ++j) { if (!vis[j] && isConnected[i][j]) { @@ -250,11 +250,11 @@ impl Solution { 我们也可以用并查集维护每个连通分量,初始时,每个城市都属于不同的连通分量,所以省份数量为 $n$。 -接下来,遍历矩阵 $isConnected$,如果两个城市 $(i, j)$ 之间有相连关系,并且处于两个不同的连通分量,则它们将被合并成为一个连通分量,然后将省份数量减去 $1$。 +接下来,遍历矩阵 $\textit{isConnected}$,如果两个城市 $(i, j)$ 之间有相连关系,并且处于两个不同的连通分量,则它们将被合并成为一个连通分量,然后将省份数量减去 $1$。 最后返回省份数量即可。 -时间复杂度 $O(n^2 \times \alpha(n))$,空间复杂度 $O(n)$。其中 $n$ 是城市的数量,而 $\alpha$ 是阿克曼函数的反函数,在渐进意义下 $\alpha(n)$ 可以认为是一个很小的常数。 +时间复杂度 $O(n^2 \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是城市的数量,而 $\log n$ 是并查集的路径压缩的时间复杂度。 @@ -326,7 +326,7 @@ public: int n = isConnected.size(); int p[n]; iota(p, p + n, 0); - function find = [&](int x) -> int { + auto find = [&](this auto&& find, int x) -> int { if (p[x] != x) { p[x] = find(p[x]); } @@ -386,10 +386,7 @@ func findCircleNum(isConnected [][]int) (ans int) { ```ts function findCircleNum(isConnected: number[][]): number { const n = isConnected.length; - const p: number[] = new Array(n); - for (let i = 0; i < n; ++i) { - p[i] = i; - } + const p: number[] = Array.from({ length: n }, (_, i) => i); const find = (x: number): number => { if (p[x] !== x) { p[x] = find(p[x]); diff --git a/solution/0500-0599/0547.Number of Provinces/README_EN.md b/solution/0500-0599/0547.Number of Provinces/README_EN.md index 40eac94422c1e..3bd86a0a10be8 100644 --- a/solution/0500-0599/0547.Number of Provinces/README_EN.md +++ b/solution/0500-0599/0547.Number of Provinces/README_EN.md @@ -60,7 +60,15 @@ tags: -### Solution 1 +### Solution 1: DFS + +We create an array $\textit{vis}$ to record whether each city has been visited. + +Next, we traverse each city $i$. If the city has not been visited, we start a depth-first search from that city. Using the matrix $\textit{isConnected}$, we find the cities directly connected to this city. These cities and the current city belong to the same province. We continue the depth-first search for these cities until all cities in the same province have been visited. This counts as one province, so we increment the answer $\textit{ans}$ by $1$. Then, we move to the next unvisited city and repeat the process until all cities have been traversed. + +Finally, return the answer. + +The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Here, $n$ is the number of cities. @@ -127,7 +135,7 @@ public: int ans = 0; bool vis[n]; memset(vis, false, sizeof(vis)); - function dfs = [&](int i) { + auto dfs = [&](this auto&& dfs, int i) -> void { vis[i] = true; for (int j = 0; j < n; ++j) { if (!vis[j] && isConnected[i][j]) { @@ -232,7 +240,15 @@ impl Solution { -### Solution 2 +### Solution 2: Union-Find + +We can also use the union-find data structure to maintain each connected component. Initially, each city belongs to a different connected component, so the number of provinces is $n$. + +Next, we traverse the matrix $\textit{isConnected}$. If there is a connection between two cities $(i, j)$ and they belong to two different connected components, they will be merged into one connected component, and the number of provinces is decremented by $1$. + +Finally, return the number of provinces. + +The time complexity is $O(n^2 \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the number of cities, and $\log n$ is the time complexity of path compression in the union-find data structure. @@ -304,7 +320,7 @@ public: int n = isConnected.size(); int p[n]; iota(p, p + n, 0); - function find = [&](int x) -> int { + auto find = [&](this auto&& find, int x) -> int { if (p[x] != x) { p[x] = find(p[x]); } @@ -364,10 +380,7 @@ func findCircleNum(isConnected [][]int) (ans int) { ```ts function findCircleNum(isConnected: number[][]): number { const n = isConnected.length; - const p: number[] = new Array(n); - for (let i = 0; i < n; ++i) { - p[i] = i; - } + const p: number[] = Array.from({ length: n }, (_, i) => i); const find = (x: number): number => { if (p[x] !== x) { p[x] = find(p[x]); diff --git a/solution/0500-0599/0547.Number of Provinces/Solution.cpp b/solution/0500-0599/0547.Number of Provinces/Solution.cpp index 84faa4a332051..3a1c73ce8923f 100644 --- a/solution/0500-0599/0547.Number of Provinces/Solution.cpp +++ b/solution/0500-0599/0547.Number of Provinces/Solution.cpp @@ -5,7 +5,7 @@ class Solution { int ans = 0; bool vis[n]; memset(vis, false, sizeof(vis)); - function dfs = [&](int i) { + auto dfs = [&](this auto&& dfs, int i) -> void { vis[i] = true; for (int j = 0; j < n; ++j) { if (!vis[j] && isConnected[i][j]) { @@ -21,4 +21,4 @@ class Solution { } return ans; } -}; \ No newline at end of file +}; diff --git a/solution/0500-0599/0547.Number of Provinces/Solution.ts b/solution/0500-0599/0547.Number of Provinces/Solution.ts index 834fe59b72c4b..cd395b2465a4f 100644 --- a/solution/0500-0599/0547.Number of Provinces/Solution.ts +++ b/solution/0500-0599/0547.Number of Provinces/Solution.ts @@ -1,6 +1,6 @@ function findCircleNum(isConnected: number[][]): number { const n = isConnected.length; - const vis: boolean[] = new Array(n).fill(false); + const vis: boolean[] = Array(n).fill(false); const dfs = (i: number) => { vis[i] = true; for (let j = 0; j < n; ++j) { diff --git a/solution/0500-0599/0547.Number of Provinces/Solution2.cpp b/solution/0500-0599/0547.Number of Provinces/Solution2.cpp index c466dfc6cf782..5f5acbf92892a 100644 --- a/solution/0500-0599/0547.Number of Provinces/Solution2.cpp +++ b/solution/0500-0599/0547.Number of Provinces/Solution2.cpp @@ -4,7 +4,7 @@ class Solution { int n = isConnected.size(); int p[n]; iota(p, p + n, 0); - function find = [&](int x) -> int { + auto find = [&](this auto&& find, int x) -> int { if (p[x] != x) { p[x] = find(p[x]); } @@ -24,4 +24,4 @@ class Solution { } return ans; } -}; \ No newline at end of file +}; diff --git a/solution/0500-0599/0547.Number of Provinces/Solution2.ts b/solution/0500-0599/0547.Number of Provinces/Solution2.ts index 2488b343ae76e..9ab3ddbe37505 100644 --- a/solution/0500-0599/0547.Number of Provinces/Solution2.ts +++ b/solution/0500-0599/0547.Number of Provinces/Solution2.ts @@ -1,9 +1,6 @@ function findCircleNum(isConnected: number[][]): number { const n = isConnected.length; - const p: number[] = new Array(n); - for (let i = 0; i < n; ++i) { - p[i] = i; - } + const p: number[] = Array.from({ length: n }, (_, i) => i); const find = (x: number): number => { if (p[x] !== x) { p[x] = find(p[x]);