Skip to content

Commit b85f63b

Browse files
authored
feat: update solutions to lc problem: No.0547 (#3974)
No.0547.Number of Provinces
1 parent 66418a9 commit b85f63b

File tree

6 files changed

+34
-27
lines changed

6 files changed

+34
-27
lines changed

solution/0500-0599/0547.Number of Provinces/README.md

+7-10
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ tags:
6868

6969
### 方法一:DFS
7070

71-
我们创建一个数组 $vis$,用于记录每个城市是否被访问过。
71+
我们创建一个数组 $\textit{vis}$,用于记录每个城市是否被访问过。
7272

73-
接下来,遍历每个城市 $i$,如果该城市未被访问过,则从该城市开始深度优先搜索,通过矩阵 $isConnected$ 得到与该城市直接相连的城市有哪些,这些城市和该城市属于同一个省,然后对这些城市继续深度优先搜索,直到同一个省的所有城市都被访问到,即可得到一个省,将答案 $ans$ 加 $1$,然后遍历下一个未被访问过的城市,直到遍历完所有的城市。
73+
接下来,遍历每个城市 $i$,如果该城市未被访问过,则从该城市开始深度优先搜索,通过矩阵 $\textit{isConnected}$ 得到与该城市直接相连的城市有哪些,这些城市和该城市属于同一个省,然后对这些城市继续深度优先搜索,直到同一个省的所有城市都被访问到,即可得到一个省,将答案 $\textit{ans}$ 加 $1$,然后遍历下一个未被访问过的城市,直到遍历完所有的城市。
7474

7575
最后返回答案即可。
7676

@@ -141,7 +141,7 @@ public:
141141
int ans = 0;
142142
bool vis[n];
143143
memset(vis, false, sizeof(vis));
144-
function<void(int)> dfs = [&](int i) {
144+
auto dfs = [&](this auto&& dfs, int i) -> void {
145145
vis[i] = true;
146146
for (int j = 0; j < n; ++j) {
147147
if (!vis[j] && isConnected[i][j]) {
@@ -250,11 +250,11 @@ impl Solution {
250250

251251
我们也可以用并查集维护每个连通分量,初始时,每个城市都属于不同的连通分量,所以省份数量为 $n$。
252252

253-
接下来,遍历矩阵 $isConnected$,如果两个城市 $(i, j)$ 之间有相连关系,并且处于两个不同的连通分量,则它们将被合并成为一个连通分量,然后将省份数量减去 $1$。
253+
接下来,遍历矩阵 $\textit{isConnected}$,如果两个城市 $(i, j)$ 之间有相连关系,并且处于两个不同的连通分量,则它们将被合并成为一个连通分量,然后将省份数量减去 $1$。
254254

255255
最后返回省份数量即可。
256256

257-
时间复杂度 $O(n^2 \times \alpha(n))$,空间复杂度 $O(n)$。其中 $n$ 是城市的数量,而 $\alpha$ 是阿克曼函数的反函数,在渐进意义下 $\alpha(n)$ 可以认为是一个很小的常数
257+
时间复杂度 $O(n^2 \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是城市的数量,而 $\log n$ 是并查集的路径压缩的时间复杂度
258258

259259
<!-- tabs:start -->
260260

@@ -326,7 +326,7 @@ public:
326326
int n = isConnected.size();
327327
int p[n];
328328
iota(p, p + n, 0);
329-
function<int(int)> find = [&](int x) -> int {
329+
auto find = [&](this auto&& find, int x) -> int {
330330
if (p[x] != x) {
331331
p[x] = find(p[x]);
332332
}
@@ -386,10 +386,7 @@ func findCircleNum(isConnected [][]int) (ans int) {
386386
```ts
387387
function findCircleNum(isConnected: number[][]): number {
388388
const n = isConnected.length;
389-
const p: number[] = new Array(n);
390-
for (let i = 0; i < n; ++i) {
391-
p[i] = i;
392-
}
389+
const p: number[] = Array.from({ length: n }, (_, i) => i);
393390
const find = (x: number): number => {
394391
if (p[x] !== x) {
395392
p[x] = find(p[x]);

solution/0500-0599/0547.Number of Provinces/README_EN.md

+21-8
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,15 @@ tags:
6060

6161
<!-- solution:start -->
6262

63-
### Solution 1
63+
### Solution 1: DFS
64+
65+
We create an array $\textit{vis}$ to record whether each city has been visited.
66+
67+
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.
68+
69+
Finally, return the answer.
70+
71+
The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Here, $n$ is the number of cities.
6472

6573
<!-- tabs:start -->
6674

@@ -127,7 +135,7 @@ public:
127135
int ans = 0;
128136
bool vis[n];
129137
memset(vis, false, sizeof(vis));
130-
function<void(int)> dfs = [&](int i) {
138+
auto dfs = [&](this auto&& dfs, int i) -> void {
131139
vis[i] = true;
132140
for (int j = 0; j < n; ++j) {
133141
if (!vis[j] && isConnected[i][j]) {
@@ -232,7 +240,15 @@ impl Solution {
232240

233241
<!-- solution:start -->
234242

235-
### Solution 2
243+
### Solution 2: Union-Find
244+
245+
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$.
246+
247+
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$.
248+
249+
Finally, return the number of provinces.
250+
251+
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.
236252

237253
<!-- tabs:start -->
238254

@@ -304,7 +320,7 @@ public:
304320
int n = isConnected.size();
305321
int p[n];
306322
iota(p, p + n, 0);
307-
function<int(int)> find = [&](int x) -> int {
323+
auto find = [&](this auto&& find, int x) -> int {
308324
if (p[x] != x) {
309325
p[x] = find(p[x]);
310326
}
@@ -364,10 +380,7 @@ func findCircleNum(isConnected [][]int) (ans int) {
364380
```ts
365381
function findCircleNum(isConnected: number[][]): number {
366382
const n = isConnected.length;
367-
const p: number[] = new Array(n);
368-
for (let i = 0; i < n; ++i) {
369-
p[i] = i;
370-
}
383+
const p: number[] = Array.from({ length: n }, (_, i) => i);
371384
const find = (x: number): number => {
372385
if (p[x] !== x) {
373386
p[x] = find(p[x]);

solution/0500-0599/0547.Number of Provinces/Solution.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class Solution {
55
int ans = 0;
66
bool vis[n];
77
memset(vis, false, sizeof(vis));
8-
function<void(int)> dfs = [&](int i) {
8+
auto dfs = [&](this auto&& dfs, int i) -> void {
99
vis[i] = true;
1010
for (int j = 0; j < n; ++j) {
1111
if (!vis[j] && isConnected[i][j]) {
@@ -21,4 +21,4 @@ class Solution {
2121
}
2222
return ans;
2323
}
24-
};
24+
};

solution/0500-0599/0547.Number of Provinces/Solution.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
function findCircleNum(isConnected: number[][]): number {
22
const n = isConnected.length;
3-
const vis: boolean[] = new Array(n).fill(false);
3+
const vis: boolean[] = Array(n).fill(false);
44
const dfs = (i: number) => {
55
vis[i] = true;
66
for (let j = 0; j < n; ++j) {

solution/0500-0599/0547.Number of Provinces/Solution2.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class Solution {
44
int n = isConnected.size();
55
int p[n];
66
iota(p, p + n, 0);
7-
function<int(int)> find = [&](int x) -> int {
7+
auto find = [&](this auto&& find, int x) -> int {
88
if (p[x] != x) {
99
p[x] = find(p[x]);
1010
}
@@ -24,4 +24,4 @@ class Solution {
2424
}
2525
return ans;
2626
}
27-
};
27+
};

solution/0500-0599/0547.Number of Provinces/Solution2.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
function findCircleNum(isConnected: number[][]): number {
22
const n = isConnected.length;
3-
const p: number[] = new Array(n);
4-
for (let i = 0; i < n; ++i) {
5-
p[i] = i;
6-
}
3+
const p: number[] = Array.from({ length: n }, (_, i) => i);
74
const find = (x: number): number => {
85
if (p[x] !== x) {
96
p[x] = find(p[x]);

0 commit comments

Comments
 (0)