From dd2660e0ab9c472bf78070f6baaf01004691b4d9 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 1 Jun 2024 19:45:23 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.323 No.323.Number of Connected Components in an Undirected Graph --- .../README.md | 182 ++++++++++++++++-- .../README_EN.md | 180 +++++++++++++++-- .../Solution3.cpp | 32 +++ .../Solution3.go | 28 +++ .../Solution3.java | 32 +++ .../Solution3.py | 21 ++ .../Solution3.ts | 41 ++-- 7 files changed, 454 insertions(+), 62 deletions(-) create mode 100644 solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.cpp create mode 100644 solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.go create mode 100644 solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.java create mode 100644 solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.py diff --git a/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/README.md b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/README.md index f4548a7fcff71..717678852aa5f 100644 --- a/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/README.md +++ b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/README.md @@ -494,39 +494,179 @@ function countComponents(n: number, edges: number[][]): number { -### 方法 3: BFS +### 方法三:BFS + +我们也可以使用 BFS 来统计图中的连通分量。 + +与方法一类似,我们首先根据给定的边构建一个邻接表 $g$,然后遍历所有节点,对于每个节点,如果它没有被访问过,我们就从该节点开始进行 BFS 遍历,将所有与其相邻的节点都标记为已访问,直到所有与其相邻的节点都被访问过,这样我们就找到了一个连通分量,答案加一。 + +遍历所有节点后,我们就得到了图中连通分量的数目。 + +时间复杂度 $O(n + m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别是节点数和边数。 -#### TypeScript +#### Python3 -```ts -function countComponents(n: number, edges: number[][]): number { - const g: number[][] = Array.from({ length: n }, () => []); - const vis = new Set(); - let ans = 0; +```python +class Solution: + def countComponents(self, n: int, edges: List[List[int]]) -> int: + g = [[] for _ in range(n)] + for a, b in edges: + g[a].append(b) + g[b].append(a) + vis = set() + ans = 0 + for i in range(n): + if i in vis: + continue + vis.add(i) + q = deque([i]) + while q: + a = q.popleft() + for b in g[a]: + if b not in vis: + vis.add(b) + q.append(b) + ans += 1 + return ans +``` + +#### Java - for (const [i, j] of edges) { - g[i].push(j); - g[j].push(i); +```java +class Solution { + public int countComponents(int n, int[][] edges) { + List[] 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); + } + int ans = 0; + boolean[] vis = new boolean[n]; + for (int i = 0; i < n; ++i) { + if (vis[i]) { + continue; + } + vis[i] = true; + ++ans; + Deque q = new ArrayDeque<>(); + q.offer(i); + while (!q.isEmpty()) { + int a = q.poll(); + for (int b : g[a]) { + if (!vis[b]) { + vis[b] = true; + q.offer(b); + } + } + } + } + return ans; } +} +``` - const dfs = (i: number) => { - if (vis.has(i)) return; +#### C++ - vis.add(i); - for (const j of g[i]) { - dfs(j); +```cpp +class Solution { +public: + int countComponents(int n, vector>& edges) { + vector g[n]; + for (auto& e : edges) { + int a = e[0], b = e[1]; + g[a].push_back(b); + g[b].push_back(a); } - }; + vector vis(n); + int ans = 0; + for (int i = 0; i < n; ++i) { + if (vis[i]) { + continue; + } + vis[i] = true; + ++ans; + queue q{{i}}; + while (!q.empty()) { + int a = q.front(); + q.pop(); + for (int b : g[a]) { + if (!vis[b]) { + vis[b] = true; + q.push(b); + } + } + } + } + return ans; + } +}; +``` - for (let i = 0; i < n; i++) { - if (vis.has(i)) continue; +#### Go - dfs(i); - ans++; - } +```go +func countComponents(n int, edges [][]int) (ans int) { + 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) + } + vis := make([]bool, n) + for i := range g { + if vis[i] { + continue + } + vis[i] = true + ans++ + q := []int{i} + for len(q) > 0 { + a := q[0] + q = q[1:] + for _, b := range g[a] { + if !vis[b] { + vis[b] = true + q = append(q, b) + } + } + } + } + return +} +``` + +#### TypeScript +```ts +function countComponents(n: number, edges: number[][]): number { + const g: number[][] = Array.from({ length: n }, () => []); + for (const [a, b] of edges) { + g[a].push(b); + g[b].push(a); + } + const vis: boolean[] = Array(n).fill(false); + let ans = 0; + for (let i = 0; i < n; ++i) { + if (vis[i]) { + continue; + } + vis[i] = true; + ++ans; + const q: number[] = [i]; + while (q.length) { + const a = q.pop()!; + for (const b of g[a]) { + if (!vis[b]) { + vis[b] = true; + q.push(b); + } + } + } + } return ans; } ``` diff --git a/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/README_EN.md b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/README_EN.md index 973a9e031a081..cd2ee66d24707 100644 --- a/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/README_EN.md +++ b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/README_EN.md @@ -491,37 +491,177 @@ function countComponents(n: number, edges: number[][]): number { ### Solution 3: BFS +We can also use BFS (Breadth-First Search) to count the number of connected components in the graph. + +Similar to Solution 1, we first construct an adjacency list $g$ based on the given edges. Then we traverse all nodes. For each node, if it has not been visited, we start BFS traversal from this node, marking all its adjacent nodes as visited, until all its adjacent nodes have been visited. In this way, we have found a connected component, and the answer is incremented by one. + +After traversing all nodes, we get the number of connected components in the graph. + +The time complexity is $O(n + m)$, and the space complexity is $O(n + m)$. Where $n$ and $m$ are the number of nodes and edges, respectively. + -#### TypeScript +#### Python3 -```ts -function countComponents(n: number, edges: number[][]): number { - const g: number[][] = Array.from({ length: n }, () => []); - const vis = new Set(); - let ans = 0; +```python +class Solution: + def countComponents(self, n: int, edges: List[List[int]]) -> int: + g = [[] for _ in range(n)] + for a, b in edges: + g[a].append(b) + g[b].append(a) + vis = set() + ans = 0 + for i in range(n): + if i in vis: + continue + vis.add(i) + q = deque([i]) + while q: + a = q.popleft() + for b in g[a]: + if b not in vis: + vis.add(b) + q.append(b) + ans += 1 + return ans +``` + +#### Java - for (const [i, j] of edges) { - g[i].push(j); - g[j].push(i); +```java +class Solution { + public int countComponents(int n, int[][] edges) { + List[] 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); + } + int ans = 0; + boolean[] vis = new boolean[n]; + for (int i = 0; i < n; ++i) { + if (vis[i]) { + continue; + } + vis[i] = true; + ++ans; + Deque q = new ArrayDeque<>(); + q.offer(i); + while (!q.isEmpty()) { + int a = q.poll(); + for (int b : g[a]) { + if (!vis[b]) { + vis[b] = true; + q.offer(b); + } + } + } + } + return ans; } +} +``` - const dfs = (i: number) => { - if (vis.has(i)) return; +#### C++ - vis.add(i); - for (const j of g[i]) { - dfs(j); +```cpp +class Solution { +public: + int countComponents(int n, vector>& edges) { + vector g[n]; + for (auto& e : edges) { + int a = e[0], b = e[1]; + g[a].push_back(b); + g[b].push_back(a); } - }; + vector vis(n); + int ans = 0; + for (int i = 0; i < n; ++i) { + if (vis[i]) { + continue; + } + vis[i] = true; + ++ans; + queue q{{i}}; + while (!q.empty()) { + int a = q.front(); + q.pop(); + for (int b : g[a]) { + if (!vis[b]) { + vis[b] = true; + q.push(b); + } + } + } + } + return ans; + } +}; +``` - for (let i = 0; i < n; i++) { - if (vis.has(i)) continue; +#### Go - dfs(i); - ans++; - } +```go +func countComponents(n int, edges [][]int) (ans int) { + 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) + } + vis := make([]bool, n) + for i := range g { + if vis[i] { + continue + } + vis[i] = true + ans++ + q := []int{i} + for len(q) > 0 { + a := q[0] + q = q[1:] + for _, b := range g[a] { + if !vis[b] { + vis[b] = true + q = append(q, b) + } + } + } + } + return +} +``` + +#### TypeScript +```ts +function countComponents(n: number, edges: number[][]): number { + const g: number[][] = Array.from({ length: n }, () => []); + for (const [a, b] of edges) { + g[a].push(b); + g[b].push(a); + } + const vis: boolean[] = Array(n).fill(false); + let ans = 0; + for (let i = 0; i < n; ++i) { + if (vis[i]) { + continue; + } + vis[i] = true; + ++ans; + const q: number[] = [i]; + while (q.length) { + const a = q.pop()!; + for (const b of g[a]) { + if (!vis[b]) { + vis[b] = true; + q.push(b); + } + } + } + } return ans; } ``` diff --git a/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.cpp b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.cpp new file mode 100644 index 0000000000000..8d03d43d904b4 --- /dev/null +++ b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.cpp @@ -0,0 +1,32 @@ +class Solution { +public: + int countComponents(int n, vector>& edges) { + vector g[n]; + for (auto& e : edges) { + int a = e[0], b = e[1]; + g[a].push_back(b); + g[b].push_back(a); + } + vector vis(n); + int ans = 0; + for (int i = 0; i < n; ++i) { + if (vis[i]) { + continue; + } + vis[i] = true; + ++ans; + queue q{{i}}; + while (!q.empty()) { + int a = q.front(); + q.pop(); + for (int b : g[a]) { + if (!vis[b]) { + vis[b] = true; + q.push(b); + } + } + } + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.go b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.go new file mode 100644 index 0000000000000..8dab231e8ea80 --- /dev/null +++ b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.go @@ -0,0 +1,28 @@ +func countComponents(n int, edges [][]int) (ans int) { + 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) + } + vis := make([]bool, n) + for i := range g { + if vis[i] { + continue + } + vis[i] = true + ans++ + q := []int{i} + for len(q) > 0 { + a := q[0] + q = q[1:] + for _, b := range g[a] { + if !vis[b] { + vis[b] = true + q = append(q, b) + } + } + } + } + return +} \ No newline at end of file diff --git a/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.java b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.java new file mode 100644 index 0000000000000..c64d0c4403a78 --- /dev/null +++ b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.java @@ -0,0 +1,32 @@ +class Solution { + public int countComponents(int n, int[][] edges) { + List[] 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); + } + int ans = 0; + boolean[] vis = new boolean[n]; + for (int i = 0; i < n; ++i) { + if (vis[i]) { + continue; + } + vis[i] = true; + ++ans; + Deque q = new ArrayDeque<>(); + q.offer(i); + while (!q.isEmpty()) { + int a = q.poll(); + for (int b : g[a]) { + if (!vis[b]) { + vis[b] = true; + q.offer(b); + } + } + } + } + return ans; + } +} \ No newline at end of file diff --git a/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.py b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.py new file mode 100644 index 0000000000000..cd15c5322e365 --- /dev/null +++ b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.py @@ -0,0 +1,21 @@ +class Solution: + def countComponents(self, n: int, edges: List[List[int]]) -> int: + g = [[] for _ in range(n)] + for a, b in edges: + g[a].append(b) + g[b].append(a) + vis = set() + ans = 0 + for i in range(n): + if i in vis: + continue + vis.add(i) + q = deque([i]) + while q: + a = q.popleft() + for b in g[a]: + if b not in vis: + vis.add(b) + q.append(b) + ans += 1 + return ans diff --git a/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.ts b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.ts index 18a3afec2fd52..14ff21daffa41 100644 --- a/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.ts +++ b/solution/0300-0399/0323.Number of Connected Components in an Undirected Graph/Solution3.ts @@ -1,28 +1,27 @@ function countComponents(n: number, edges: number[][]): number { const g: number[][] = Array.from({ length: n }, () => []); - const vis = new Set(); - let ans = 0; - - for (const [i, j] of edges) { - g[i].push(j); - g[j].push(i); + for (const [a, b] of edges) { + g[a].push(b); + g[b].push(a); } - - const dfs = (i: number) => { - if (vis.has(i)) return; - - vis.add(i); - for (const j of g[i]) { - dfs(j); + const vis: boolean[] = Array(n).fill(false); + let ans = 0; + for (let i = 0; i < n; ++i) { + if (vis[i]) { + continue; + } + vis[i] = true; + ++ans; + const q: number[] = [i]; + while (q.length) { + const a = q.pop()!; + for (const b of g[a]) { + if (!vis[b]) { + vis[b] = true; + q.push(b); + } + } } - }; - - for (let i = 0; i < n; i++) { - if (vis.has(i)) continue; - - dfs(i); - ans++; } - return ans; }