From 99a7ad0d0d9f8ce05fbd7f930ee7d544403e85a5 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Mon, 29 Jan 2024 20:14:09 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.0130 No.0130.Surrounded Regions --- .../0130.Surrounded Regions/README.md | 411 +++++++++--------- .../0130.Surrounded Regions/README_EN.md | 411 +++++++++--------- .../0130.Surrounded Regions/Solution.cpp | 43 +- .../0130.Surrounded Regions/Solution.cs | 99 ++--- .../0130.Surrounded Regions/Solution.go | 29 +- .../0130.Surrounded Regions/Solution.java | 22 +- .../0130.Surrounded Regions/Solution.py | 34 +- .../0130.Surrounded Regions/Solution.rs | 63 +-- .../0130.Surrounded Regions/Solution.ts | 37 +- .../0130.Surrounded Regions/Solution2.cpp | 36 +- .../0130.Surrounded Regions/Solution2.go | 2 +- .../0130.Surrounded Regions/Solution2.py | 18 +- .../0130.Surrounded Regions/Solution2.ts | 29 +- 13 files changed, 602 insertions(+), 632 deletions(-) diff --git a/solution/0100-0199/0130.Surrounded Regions/README.md b/solution/0100-0199/0130.Surrounded Regions/README.md index 74ed25ff327d4..700df4c866eaf 100644 --- a/solution/0100-0199/0130.Surrounded Regions/README.md +++ b/solution/0100-0199/0130.Surrounded Regions/README.md @@ -42,41 +42,47 @@ ## 解法 -### 方法一 +### 方法一:DFS + +我们可以从矩阵的边界开始,将矩阵边界上的每个 `O` 作为起始点,开始进行深度优先搜索。将搜索到的 `O` 全部替换成 `.`。 + +然后我们再遍历这个矩阵,对于每个位置: + +- 如果是 `.`,则替换成 `O`; +- 否则如果是 `O`,则替换成 `X`。 + +时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。 ```python class Solution: def solve(self, board: List[List[str]]) -> None: - """ - Do not return anything, modify board in-place instead. - """ - - def dfs(i, j): - board[i][j] = '.' - for a, b in [[0, -1], [0, 1], [1, 0], [-1, 0]]: - x, y = i + a, j + b - if 0 <= x < m and 0 <= y < n and board[x][y] == 'O': - dfs(x, y) + def dfs(i: int, j: int): + if not (0 <= i < m and 0 <= j < n and board[i][j] == "O"): + return + board[i][j] = "." + for a, b in pairwise((-1, 0, 1, 0, -1)): + dfs(i + a, j + b) m, n = len(board), len(board[0]) for i in range(m): - for j in range(n): - if board[i][j] == 'O' and ( - i == 0 or i == m - 1 or j == 0 or j == n - 1 - ): - dfs(i, j) + dfs(i, 0) + dfs(i, n - 1) + for j in range(n): + dfs(0, j) + dfs(m - 1, j) for i in range(m): for j in range(n): - if board[i][j] == 'O': - board[i][j] = 'X' - elif board[i][j] == '.': - board[i][j] = 'O' + if board[i][j] == ".": + board[i][j] = "O" + elif board[i][j] == "O": + board[i][j] = "X" ``` ```java class Solution { + private final int[] dirs = {-1, 0, 1, 0, -1}; private char[][] board; private int m; private int n; @@ -86,11 +92,12 @@ class Solution { n = board[0].length; this.board = board; for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && board[i][j] == 'O') { - dfs(i, j); - } - } + dfs(i, 0); + dfs(i, n - 1); + } + for (int j = 0; j < n; ++j) { + dfs(0, j); + dfs(m - 1, j); } for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { @@ -104,14 +111,12 @@ class Solution { } private void dfs(int i, int j) { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O') { + return; + } board[i][j] = '.'; - int[] dirs = {-1, 0, 1, 0, -1}; for (int k = 0; k < 4; ++k) { - int x = i + dirs[k]; - int y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') { - dfs(x, y); - } + dfs(i + dirs[k], j + dirs[k + 1]); } } } @@ -122,27 +127,32 @@ class Solution { public: void solve(vector>& board) { int m = board.size(), n = board[0].size(); - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && board[i][j] == 'O') - dfs(board, i, j); - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if (board[i][j] == '.') - board[i][j] = 'O'; - else if (board[i][j] == 'O') - board[i][j] = 'X'; + int dirs[5] = {-1, 0, 1, 0, -1}; + function dfs = [&](int i, int j) { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O') { + return; + } + board[i][j] = '.'; + for (int k = 0; k < 4; ++k) { + dfs(i + dirs[k], j + dirs[k + 1]); } + }; + for (int i = 0; i < m; ++i) { + dfs(i, 0); + dfs(i, n - 1); } - } - - void dfs(vector>& board, int i, int j) { - board[i][j] = '.'; - vector dirs = {-1, 0, 1, 0, -1}; - for (int k = 0; k < 4; ++k) { - int x = i + dirs[k], y = j + dirs[k + 1]; - if (x >= 0 && x < board.size() && y >= 0 && y < board[0].size() && board[x][y] == 'O') - dfs(board, x, y); + for (int j = 1; j < n - 1; ++j) { + dfs(0, j); + dfs(m - 1, j); + } + for (auto& row : board) { + for (auto& c : row) { + if (c == '.') { + c = 'O'; + } else if (c == 'O') { + c = 'X'; + } + } } } }; @@ -151,29 +161,30 @@ public: ```go func solve(board [][]byte) { m, n := len(board), len(board[0]) + dirs := [5]int{-1, 0, 1, 0, -1} var dfs func(i, j int) dfs = func(i, j int) { + if i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O' { + return + } board[i][j] = '.' - dirs := []int{-1, 0, 1, 0, -1} for k := 0; k < 4; k++ { - x, y := i+dirs[k], j+dirs[k+1] - if x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O' { - dfs(x, y) - } + dfs(i+dirs[k], j+dirs[k+1]) } } for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - if (i == 0 || i == m-1 || j == 0 || j == n-1) && board[i][j] == 'O' { - dfs(i, j) - } - } + dfs(i, 0) + dfs(i, n-1) } - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - if board[i][j] == '.' { + for j := 0; j < n; j++ { + dfs(0, j) + dfs(m-1, j) + } + for i, row := range board { + for j, c := range row { + if c == '.' { board[i][j] = 'O' - } else if board[i][j] == 'O' { + } else if c == 'O' { board[i][j] = 'X' } } @@ -182,35 +193,32 @@ func solve(board [][]byte) { ``` ```ts -/** - Do not return anything, modify board in-place instead. - */ function solve(board: string[][]): void { - function dfs(i, j) { + const m = board.length; + const n = board[0].length; + const dirs: number[] = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number): void => { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] !== 'O') { + return; + } board[i][j] = '.'; - const dirs = [-1, 0, 1, 0, -1]; for (let k = 0; k < 4; ++k) { - const x = i + dirs[k]; - const y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') { - dfs(x, y); - } + dfs(i + dirs[k], j + dirs[k + 1]); } - } - const m = board.length; - const n = board[0].length; + }; for (let i = 0; i < m; ++i) { - for (let j = 0; j < n; ++j) { - if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && board[i][j] == 'O') { - dfs(i, j); - } - } + dfs(i, 0); + dfs(i, n - 1); + } + for (let j = 0; j < n; ++j) { + dfs(0, j); + dfs(m - 1, j); } for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - if (board[i][j] == '.') { + if (board[i][j] === '.') { board[i][j] = 'O'; - } else if (board[i][j] == 'O') { + } else if (board[i][j] === 'O') { board[i][j] = 'X'; } } @@ -220,43 +228,50 @@ function solve(board: string[][]): void { ```rust impl Solution { - fn dfs(i: usize, j: usize, mark: char, vis: &mut Vec>, board: &mut Vec>) { - if vis[i][j] || board[i][j] != mark { - return; - } - vis[i][j] = true; - if i > 0 { - Self::dfs(i - 1, j, mark, vis, board); - } - if i < vis.len() - 1 { - Self::dfs(i + 1, j, mark, vis, board); - } - if j > 0 { - Self::dfs(i, j - 1, mark, vis, board); - } - if j < vis[0].len() - 1 { - Self::dfs(i, j + 1, mark, vis, board); - } - } - pub fn solve(board: &mut Vec>) { let m = board.len(); let n = board[0].len(); - let mut vis = vec![vec![false; n]; m]; + let dirs = vec![-1, 0, 1, 0, -1]; + + fn dfs( + board: &mut Vec>, + i: usize, + j: usize, + dirs: &Vec, + m: usize, + n: usize + ) { + if i >= 0 && i < m && j >= 0 && j < n && board[i][j] == 'O' { + board[i][j] = '.'; + for k in 0..4 { + dfs( + board, + ((i as i32) + dirs[k]) as usize, + ((j as i32) + dirs[k + 1]) as usize, + dirs, + m, + n + ); + } + } + } + for i in 0..m { - Self::dfs(i, 0, board[i][0], &mut vis, board); - Self::dfs(i, n - 1, board[i][n - 1], &mut vis, board); + dfs(board, i, 0, &dirs, m, n); + dfs(board, i, n - 1, &dirs, m, n); } - for i in 0..n { - Self::dfs(0, i, board[0][i], &mut vis, board); - Self::dfs(m - 1, i, board[m - 1][i], &mut vis, board); + for j in 0..n { + dfs(board, 0, j, &dirs, m, n); + dfs(board, m - 1, j, &dirs, m, n); } + for i in 0..m { for j in 0..n { - if vis[i][j] { - continue; + if board[i][j] == '.' { + board[i][j] = 'O'; + } else if board[i][j] == 'O' { + board[i][j] = 'X'; } - board[i][j] = 'X'; } } } @@ -264,82 +279,65 @@ impl Solution { ``` ```cs -using System; -using System.Collections.Generic; - public class Solution { - private static readonly int[,] directions = new int[4, 2] { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 }}; + private readonly int[] dirs = {-1, 0, 1, 0, -1}; + private char[][] board; + private int m; + private int n; + public void Solve(char[][] board) { - var lenI = board.Length; - var lenJ = lenI == 0 ? 0 : board[0].Length; - - for (var i = 0; i < lenI; ++i) - { - for (var j = 0; j < lenJ; ++j) - { - if (board[i][j] == 'O') - { - var marked = new List>(); - marked.Add(Tuple.Create(i, j)); - board[i][j] = 'M'; - bool escaped = false; - for (var m = 0; m < marked.Count; ++m) - { - for (var k = 0; k < 4; ++k) - { - var newI = marked[m].Item1 + directions[k, 0]; - var newJ = marked[m].Item2 + directions[k, 1]; - if (newI < 0 || newI >= lenI || newJ < 0 || newJ >= lenJ) - { - escaped = true; - } - else if (board[newI][newJ] == 'O') - { - board[newI][newJ] = 'M'; - marked.Add(Tuple.Create(newI, newJ)); - } - } - } + m = board.Length; + n = board[0].Length; + this.board = board; - if (!escaped) - { - foreach (var item in marked) - { - board[item.Item1][item.Item2] = 'X'; - } - } - } - } + for (int i = 0; i < m; ++i) { + Dfs(i, 0); + Dfs(i, n - 1); + } + for (int j = 0; j < n; ++j) { + Dfs(0, j); + Dfs(m - 1, j); } - for (var i = 0; i < lenI; ++i) - { - for (var j = 0; j < lenJ; ++j) - { - if (board[i][j] == 'M') - { + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (board[i][j] == '.') { board[i][j] = 'O'; + } else if (board[i][j] == 'O') { + board[i][j] = 'X'; } } } } + + private void Dfs(int i, int j) { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O') { + return; + } + board[i][j] = '.'; + for (int k = 0; k < 4; ++k) { + Dfs(i + dirs[k], j + dirs[k + 1]); + } + } } ``` -### 方法二 +### 方法二:并查集 + +我们也可以使用并查集,将矩阵边界上的每个 `O` 与一个超级节点 $m \times n$ 相连,将矩阵中的每个 `O` 与其上下左右的 `O` 相连。 + +然后我们遍历这个矩阵,对于每个位置,如果是 `O`,并且其与超级节点不相连,则将其替换成 `X`。 + +时间复杂度 $O(m \times n \times \alpha(m \times n))$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数,$\alpha$ 是阿克曼函数的反函数。 ```python class Solution: def solve(self, board: List[List[str]]) -> None: - """ - Do not return anything, modify board in-place instead. - """ - - def find(x): + def find(x: int) -> int: if p[x] != x: p[x] = find(p[x]) return p[x] @@ -348,18 +346,18 @@ class Solution: p = list(range(m * n + 1)) for i in range(m): for j in range(n): - if board[i][j] == 'O': - if i == 0 or i == m - 1 or j == 0 or j == n - 1: + if board[i][j] == "O": + if i in (0, m - 1) or j in (0, n - 1): p[find(i * n + j)] = find(m * n) else: - for a, b in [(-1, 0), (1, 0), (0, -1), (0, 1)]: + for a, b in pairwise((-1, 0, 1, 0, -1)): x, y = i + a, j + b - if board[x][y] == 'O': + if board[x][y] == "O": p[find(x * n + y)] = find(i * n + j) for i in range(m): for j in range(n): - if board[i][j] == 'O' and find(i * n + j) != find(m * n): - board[i][j] = 'X' + if board[i][j] == "O" and find(i * n + j) != find(m * n): + board[i][j] = "X" ``` ```java @@ -412,36 +410,38 @@ class Solution { ```cpp class Solution { public: - vector p; - void solve(vector>& board) { int m = board.size(), n = board[0].size(); - p.resize(m * n + 1); - for (int i = 0; i < p.size(); ++i) p[i] = i; - vector dirs = {-1, 0, 1, 0, -1}; + vector p(m * n + 1); + iota(p.begin(), p.end(), 0); + function find = [&](int x) { + return p[x] == x ? x : p[x] = find(p[x]); + }; + int dirs[5] = {-1, 0, 1, 0, -1}; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (board[i][j] == 'O') { - if (i == 0 || i == m - 1 || j == 0 || j == n - 1) + if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { p[find(i * n + j)] = find(m * n); - else { + } else { for (int k = 0; k < 4; ++k) { - int x = i + dirs[k], y = j + dirs[k + 1]; - if (board[x][y] == 'O') p[find(x * n + y)] = find(i * n + j); + int x = i + dirs[k]; + int y = j + dirs[k + 1]; + if (board[x][y] == 'O') { + p[find(x * n + y)] = find(i * n + j); + } } } } } } - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - if (board[i][j] == 'O' && find(i * n + j) != find(m * n)) + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (board[i][j] == 'O' && find(i * n + j) != find(m * n)) { board[i][j] = 'X'; - } - - int find(int x) { - if (p[x] != x) p[x] = find(p[x]); - return p[x]; + } + } + } } }; ``` @@ -460,7 +460,7 @@ func solve(board [][]byte) { } return p[x] } - dirs := []int{-1, 0, 1, 0, -1} + dirs := [5]int{-1, 0, 1, 0, -1} for i := 0; i < m; i++ { for j := 0; j < n; j++ { if board[i][j] == 'O' { @@ -488,33 +488,28 @@ func solve(board [][]byte) { ``` ```ts -/** - Do not return anything, modify board in-place instead. - */ function solve(board: string[][]): void { const m = board.length; const n = board[0].length; - let p = new Array(m * n + 1); - for (let i = 0; i < p.length; ++i) { - p[i] = i; - } - function find(x) { - if (p[x] != x) { + const p: number[] = Array(m * n + 1) + .fill(0) + .map((_, i) => i); + const dirs: number[] = [-1, 0, 1, 0, -1]; + const find = (x: number): number => { + if (p[x] !== x) { p[x] = find(p[x]); } return p[x]; - } - const dirs = [-1, 0, 1, 0, -1]; + }; for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - if (board[i][j] == 'O') { - if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { + if (board[i][j] === 'O') { + if (i === 0 || i === m - 1 || j === 0 || j === n - 1) { p[find(i * n + j)] = find(m * n); } else { for (let k = 0; k < 4; ++k) { - const x = i + dirs[k]; - const y = j + dirs[k + 1]; - if (board[x][y] == 'O') { + const [x, y] = [i + dirs[k], j + dirs[k + 1]]; + if (board[x][y] === 'O') { p[find(x * n + y)] = find(i * n + j); } } @@ -524,7 +519,7 @@ function solve(board: string[][]): void { } for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - if (board[i][j] == 'O' && find(i * n + j) != find(m * n)) { + if (board[i][j] === 'O' && find(i * n + j) !== find(m * n)) { board[i][j] = 'X'; } } diff --git a/solution/0100-0199/0130.Surrounded Regions/README_EN.md b/solution/0100-0199/0130.Surrounded Regions/README_EN.md index 1896ad29bc47e..9bd840208675c 100644 --- a/solution/0100-0199/0130.Surrounded Regions/README_EN.md +++ b/solution/0100-0199/0130.Surrounded Regions/README_EN.md @@ -40,41 +40,47 @@ The other three 'O' form a surrounded region, so they are flipped. ## Solutions -### Solution 1 +### Solution 1: Depth-First Search (DFS) + +We can start from the boundary of the matrix, taking each 'O' on the matrix boundary as a starting point, and perform depth-first search. All 'O's found in the search are replaced with '.'. + +Then we traverse the matrix again, for each position: + +- If it is '.', replace it with 'O'; +- Otherwise, if it is 'O', replace it with 'X'. + +The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the number of rows and columns in the matrix, respectively. ```python class Solution: def solve(self, board: List[List[str]]) -> None: - """ - Do not return anything, modify board in-place instead. - """ - - def dfs(i, j): - board[i][j] = '.' - for a, b in [[0, -1], [0, 1], [1, 0], [-1, 0]]: - x, y = i + a, j + b - if 0 <= x < m and 0 <= y < n and board[x][y] == 'O': - dfs(x, y) + def dfs(i: int, j: int): + if not (0 <= i < m and 0 <= j < n and board[i][j] == "O"): + return + board[i][j] = "." + for a, b in pairwise((-1, 0, 1, 0, -1)): + dfs(i + a, j + b) m, n = len(board), len(board[0]) for i in range(m): - for j in range(n): - if board[i][j] == 'O' and ( - i == 0 or i == m - 1 or j == 0 or j == n - 1 - ): - dfs(i, j) + dfs(i, 0) + dfs(i, n - 1) + for j in range(n): + dfs(0, j) + dfs(m - 1, j) for i in range(m): for j in range(n): - if board[i][j] == 'O': - board[i][j] = 'X' - elif board[i][j] == '.': - board[i][j] = 'O' + if board[i][j] == ".": + board[i][j] = "O" + elif board[i][j] == "O": + board[i][j] = "X" ``` ```java class Solution { + private final int[] dirs = {-1, 0, 1, 0, -1}; private char[][] board; private int m; private int n; @@ -84,11 +90,12 @@ class Solution { n = board[0].length; this.board = board; for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && board[i][j] == 'O') { - dfs(i, j); - } - } + dfs(i, 0); + dfs(i, n - 1); + } + for (int j = 0; j < n; ++j) { + dfs(0, j); + dfs(m - 1, j); } for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { @@ -102,14 +109,12 @@ class Solution { } private void dfs(int i, int j) { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O') { + return; + } board[i][j] = '.'; - int[] dirs = {-1, 0, 1, 0, -1}; for (int k = 0; k < 4; ++k) { - int x = i + dirs[k]; - int y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') { - dfs(x, y); - } + dfs(i + dirs[k], j + dirs[k + 1]); } } } @@ -120,27 +125,32 @@ class Solution { public: void solve(vector>& board) { int m = board.size(), n = board[0].size(); - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && board[i][j] == 'O') - dfs(board, i, j); - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if (board[i][j] == '.') - board[i][j] = 'O'; - else if (board[i][j] == 'O') - board[i][j] = 'X'; + int dirs[5] = {-1, 0, 1, 0, -1}; + function dfs = [&](int i, int j) { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O') { + return; + } + board[i][j] = '.'; + for (int k = 0; k < 4; ++k) { + dfs(i + dirs[k], j + dirs[k + 1]); } + }; + for (int i = 0; i < m; ++i) { + dfs(i, 0); + dfs(i, n - 1); } - } - - void dfs(vector>& board, int i, int j) { - board[i][j] = '.'; - vector dirs = {-1, 0, 1, 0, -1}; - for (int k = 0; k < 4; ++k) { - int x = i + dirs[k], y = j + dirs[k + 1]; - if (x >= 0 && x < board.size() && y >= 0 && y < board[0].size() && board[x][y] == 'O') - dfs(board, x, y); + for (int j = 1; j < n - 1; ++j) { + dfs(0, j); + dfs(m - 1, j); + } + for (auto& row : board) { + for (auto& c : row) { + if (c == '.') { + c = 'O'; + } else if (c == 'O') { + c = 'X'; + } + } } } }; @@ -149,29 +159,30 @@ public: ```go func solve(board [][]byte) { m, n := len(board), len(board[0]) + dirs := [5]int{-1, 0, 1, 0, -1} var dfs func(i, j int) dfs = func(i, j int) { + if i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O' { + return + } board[i][j] = '.' - dirs := []int{-1, 0, 1, 0, -1} for k := 0; k < 4; k++ { - x, y := i+dirs[k], j+dirs[k+1] - if x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O' { - dfs(x, y) - } + dfs(i+dirs[k], j+dirs[k+1]) } } for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - if (i == 0 || i == m-1 || j == 0 || j == n-1) && board[i][j] == 'O' { - dfs(i, j) - } - } + dfs(i, 0) + dfs(i, n-1) } - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - if board[i][j] == '.' { + for j := 0; j < n; j++ { + dfs(0, j) + dfs(m-1, j) + } + for i, row := range board { + for j, c := range row { + if c == '.' { board[i][j] = 'O' - } else if board[i][j] == 'O' { + } else if c == 'O' { board[i][j] = 'X' } } @@ -180,35 +191,32 @@ func solve(board [][]byte) { ``` ```ts -/** - Do not return anything, modify board in-place instead. - */ function solve(board: string[][]): void { - function dfs(i, j) { + const m = board.length; + const n = board[0].length; + const dirs: number[] = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number): void => { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] !== 'O') { + return; + } board[i][j] = '.'; - const dirs = [-1, 0, 1, 0, -1]; for (let k = 0; k < 4; ++k) { - const x = i + dirs[k]; - const y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') { - dfs(x, y); - } + dfs(i + dirs[k], j + dirs[k + 1]); } - } - const m = board.length; - const n = board[0].length; + }; for (let i = 0; i < m; ++i) { - for (let j = 0; j < n; ++j) { - if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && board[i][j] == 'O') { - dfs(i, j); - } - } + dfs(i, 0); + dfs(i, n - 1); + } + for (let j = 0; j < n; ++j) { + dfs(0, j); + dfs(m - 1, j); } for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - if (board[i][j] == '.') { + if (board[i][j] === '.') { board[i][j] = 'O'; - } else if (board[i][j] == 'O') { + } else if (board[i][j] === 'O') { board[i][j] = 'X'; } } @@ -218,43 +226,50 @@ function solve(board: string[][]): void { ```rust impl Solution { - fn dfs(i: usize, j: usize, mark: char, vis: &mut Vec>, board: &mut Vec>) { - if vis[i][j] || board[i][j] != mark { - return; - } - vis[i][j] = true; - if i > 0 { - Self::dfs(i - 1, j, mark, vis, board); - } - if i < vis.len() - 1 { - Self::dfs(i + 1, j, mark, vis, board); - } - if j > 0 { - Self::dfs(i, j - 1, mark, vis, board); - } - if j < vis[0].len() - 1 { - Self::dfs(i, j + 1, mark, vis, board); - } - } - pub fn solve(board: &mut Vec>) { let m = board.len(); let n = board[0].len(); - let mut vis = vec![vec![false; n]; m]; + let dirs = vec![-1, 0, 1, 0, -1]; + + fn dfs( + board: &mut Vec>, + i: usize, + j: usize, + dirs: &Vec, + m: usize, + n: usize + ) { + if i >= 0 && i < m && j >= 0 && j < n && board[i][j] == 'O' { + board[i][j] = '.'; + for k in 0..4 { + dfs( + board, + ((i as i32) + dirs[k]) as usize, + ((j as i32) + dirs[k + 1]) as usize, + dirs, + m, + n + ); + } + } + } + for i in 0..m { - Self::dfs(i, 0, board[i][0], &mut vis, board); - Self::dfs(i, n - 1, board[i][n - 1], &mut vis, board); + dfs(board, i, 0, &dirs, m, n); + dfs(board, i, n - 1, &dirs, m, n); } - for i in 0..n { - Self::dfs(0, i, board[0][i], &mut vis, board); - Self::dfs(m - 1, i, board[m - 1][i], &mut vis, board); + for j in 0..n { + dfs(board, 0, j, &dirs, m, n); + dfs(board, m - 1, j, &dirs, m, n); } + for i in 0..m { for j in 0..n { - if vis[i][j] { - continue; + if board[i][j] == '.' { + board[i][j] = 'O'; + } else if board[i][j] == 'O' { + board[i][j] = 'X'; } - board[i][j] = 'X'; } } } @@ -262,82 +277,65 @@ impl Solution { ``` ```cs -using System; -using System.Collections.Generic; - public class Solution { - private static readonly int[,] directions = new int[4, 2] { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 }}; + private readonly int[] dirs = {-1, 0, 1, 0, -1}; + private char[][] board; + private int m; + private int n; + public void Solve(char[][] board) { - var lenI = board.Length; - var lenJ = lenI == 0 ? 0 : board[0].Length; - - for (var i = 0; i < lenI; ++i) - { - for (var j = 0; j < lenJ; ++j) - { - if (board[i][j] == 'O') - { - var marked = new List>(); - marked.Add(Tuple.Create(i, j)); - board[i][j] = 'M'; - bool escaped = false; - for (var m = 0; m < marked.Count; ++m) - { - for (var k = 0; k < 4; ++k) - { - var newI = marked[m].Item1 + directions[k, 0]; - var newJ = marked[m].Item2 + directions[k, 1]; - if (newI < 0 || newI >= lenI || newJ < 0 || newJ >= lenJ) - { - escaped = true; - } - else if (board[newI][newJ] == 'O') - { - board[newI][newJ] = 'M'; - marked.Add(Tuple.Create(newI, newJ)); - } - } - } + m = board.Length; + n = board[0].Length; + this.board = board; - if (!escaped) - { - foreach (var item in marked) - { - board[item.Item1][item.Item2] = 'X'; - } - } - } - } + for (int i = 0; i < m; ++i) { + Dfs(i, 0); + Dfs(i, n - 1); + } + for (int j = 0; j < n; ++j) { + Dfs(0, j); + Dfs(m - 1, j); } - for (var i = 0; i < lenI; ++i) - { - for (var j = 0; j < lenJ; ++j) - { - if (board[i][j] == 'M') - { + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (board[i][j] == '.') { board[i][j] = 'O'; + } else if (board[i][j] == 'O') { + board[i][j] = 'X'; } } } } + + private void Dfs(int i, int j) { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O') { + return; + } + board[i][j] = '.'; + for (int k = 0; k < 4; ++k) { + Dfs(i + dirs[k], j + dirs[k + 1]); + } + } } ``` -### Solution 2 +### Solution 2: Union-Find Set + +We can also use a union-find set, connecting each 'O' on the matrix boundary with a super node $m \times n$, and connecting each 'O' in the matrix with the 'O's above, below, left, and right of it. + +Then we traverse this matrix, for each position, if it is 'O' and it is not connected to the super node, then we replace it with 'X'. + +The time complexity is $O(m \times n \times \alpha(m \times n))$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the number of rows and columns in the matrix, respectively, and $\alpha$ is the inverse Ackermann function. ```python class Solution: def solve(self, board: List[List[str]]) -> None: - """ - Do not return anything, modify board in-place instead. - """ - - def find(x): + def find(x: int) -> int: if p[x] != x: p[x] = find(p[x]) return p[x] @@ -346,18 +344,18 @@ class Solution: p = list(range(m * n + 1)) for i in range(m): for j in range(n): - if board[i][j] == 'O': - if i == 0 or i == m - 1 or j == 0 or j == n - 1: + if board[i][j] == "O": + if i in (0, m - 1) or j in (0, n - 1): p[find(i * n + j)] = find(m * n) else: - for a, b in [(-1, 0), (1, 0), (0, -1), (0, 1)]: + for a, b in pairwise((-1, 0, 1, 0, -1)): x, y = i + a, j + b - if board[x][y] == 'O': + if board[x][y] == "O": p[find(x * n + y)] = find(i * n + j) for i in range(m): for j in range(n): - if board[i][j] == 'O' and find(i * n + j) != find(m * n): - board[i][j] = 'X' + if board[i][j] == "O" and find(i * n + j) != find(m * n): + board[i][j] = "X" ``` ```java @@ -410,36 +408,38 @@ class Solution { ```cpp class Solution { public: - vector p; - void solve(vector>& board) { int m = board.size(), n = board[0].size(); - p.resize(m * n + 1); - for (int i = 0; i < p.size(); ++i) p[i] = i; - vector dirs = {-1, 0, 1, 0, -1}; + vector p(m * n + 1); + iota(p.begin(), p.end(), 0); + function find = [&](int x) { + return p[x] == x ? x : p[x] = find(p[x]); + }; + int dirs[5] = {-1, 0, 1, 0, -1}; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (board[i][j] == 'O') { - if (i == 0 || i == m - 1 || j == 0 || j == n - 1) + if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { p[find(i * n + j)] = find(m * n); - else { + } else { for (int k = 0; k < 4; ++k) { - int x = i + dirs[k], y = j + dirs[k + 1]; - if (board[x][y] == 'O') p[find(x * n + y)] = find(i * n + j); + int x = i + dirs[k]; + int y = j + dirs[k + 1]; + if (board[x][y] == 'O') { + p[find(x * n + y)] = find(i * n + j); + } } } } } } - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - if (board[i][j] == 'O' && find(i * n + j) != find(m * n)) + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (board[i][j] == 'O' && find(i * n + j) != find(m * n)) { board[i][j] = 'X'; - } - - int find(int x) { - if (p[x] != x) p[x] = find(p[x]); - return p[x]; + } + } + } } }; ``` @@ -458,7 +458,7 @@ func solve(board [][]byte) { } return p[x] } - dirs := []int{-1, 0, 1, 0, -1} + dirs := [5]int{-1, 0, 1, 0, -1} for i := 0; i < m; i++ { for j := 0; j < n; j++ { if board[i][j] == 'O' { @@ -486,33 +486,28 @@ func solve(board [][]byte) { ``` ```ts -/** - Do not return anything, modify board in-place instead. - */ function solve(board: string[][]): void { const m = board.length; const n = board[0].length; - let p = new Array(m * n + 1); - for (let i = 0; i < p.length; ++i) { - p[i] = i; - } - function find(x) { - if (p[x] != x) { + const p: number[] = Array(m * n + 1) + .fill(0) + .map((_, i) => i); + const dirs: number[] = [-1, 0, 1, 0, -1]; + const find = (x: number): number => { + if (p[x] !== x) { p[x] = find(p[x]); } return p[x]; - } - const dirs = [-1, 0, 1, 0, -1]; + }; for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - if (board[i][j] == 'O') { - if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { + if (board[i][j] === 'O') { + if (i === 0 || i === m - 1 || j === 0 || j === n - 1) { p[find(i * n + j)] = find(m * n); } else { for (let k = 0; k < 4; ++k) { - const x = i + dirs[k]; - const y = j + dirs[k + 1]; - if (board[x][y] == 'O') { + const [x, y] = [i + dirs[k], j + dirs[k + 1]]; + if (board[x][y] === 'O') { p[find(x * n + y)] = find(i * n + j); } } @@ -522,7 +517,7 @@ function solve(board: string[][]): void { } for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - if (board[i][j] == 'O' && find(i * n + j) != find(m * n)) { + if (board[i][j] === 'O' && find(i * n + j) !== find(m * n)) { board[i][j] = 'X'; } } diff --git a/solution/0100-0199/0130.Surrounded Regions/Solution.cpp b/solution/0100-0199/0130.Surrounded Regions/Solution.cpp index 824a92399a6b6..4b5379ac53ad7 100644 --- a/solution/0100-0199/0130.Surrounded Regions/Solution.cpp +++ b/solution/0100-0199/0130.Surrounded Regions/Solution.cpp @@ -2,27 +2,32 @@ class Solution { public: void solve(vector>& board) { int m = board.size(), n = board[0].size(); - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && board[i][j] == 'O') - dfs(board, i, j); - for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if (board[i][j] == '.') - board[i][j] = 'O'; - else if (board[i][j] == 'O') - board[i][j] = 'X'; + int dirs[5] = {-1, 0, 1, 0, -1}; + function dfs = [&](int i, int j) { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O') { + return; + } + board[i][j] = '.'; + for (int k = 0; k < 4; ++k) { + dfs(i + dirs[k], j + dirs[k + 1]); } + }; + for (int i = 0; i < m; ++i) { + dfs(i, 0); + dfs(i, n - 1); } - } - - void dfs(vector>& board, int i, int j) { - board[i][j] = '.'; - vector dirs = {-1, 0, 1, 0, -1}; - for (int k = 0; k < 4; ++k) { - int x = i + dirs[k], y = j + dirs[k + 1]; - if (x >= 0 && x < board.size() && y >= 0 && y < board[0].size() && board[x][y] == 'O') - dfs(board, x, y); + for (int j = 1; j < n - 1; ++j) { + dfs(0, j); + dfs(m - 1, j); + } + for (auto& row : board) { + for (auto& c : row) { + if (c == '.') { + c = 'O'; + } else if (c == 'O') { + c = 'X'; + } + } } } }; \ No newline at end of file diff --git a/solution/0100-0199/0130.Surrounded Regions/Solution.cs b/solution/0100-0199/0130.Surrounded Regions/Solution.cs index 9ddb0b2e7798b..ae9f36e43733c 100644 --- a/solution/0100-0199/0130.Surrounded Regions/Solution.cs +++ b/solution/0100-0199/0130.Surrounded Regions/Solution.cs @@ -1,60 +1,41 @@ -using System; -using System.Collections.Generic; - -public class Solution { - private static readonly int[,] directions = new int[4, 2] { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 }}; - public void Solve(char[][] board) { - var lenI = board.Length; - var lenJ = lenI == 0 ? 0 : board[0].Length; - - for (var i = 0; i < lenI; ++i) - { - for (var j = 0; j < lenJ; ++j) - { - if (board[i][j] == 'O') - { - var marked = new List>(); - marked.Add(Tuple.Create(i, j)); - board[i][j] = 'M'; - bool escaped = false; - for (var m = 0; m < marked.Count; ++m) - { - for (var k = 0; k < 4; ++k) - { - var newI = marked[m].Item1 + directions[k, 0]; - var newJ = marked[m].Item2 + directions[k, 1]; - if (newI < 0 || newI >= lenI || newJ < 0 || newJ >= lenJ) - { - escaped = true; - } - else if (board[newI][newJ] == 'O') - { - board[newI][newJ] = 'M'; - marked.Add(Tuple.Create(newI, newJ)); - } - } - } - - if (!escaped) - { - foreach (var item in marked) - { - board[item.Item1][item.Item2] = 'X'; - } - } - } - } - } - - for (var i = 0; i < lenI; ++i) - { - for (var j = 0; j < lenJ; ++j) - { - if (board[i][j] == 'M') - { - board[i][j] = 'O'; - } - } - } - } +public class Solution { + private readonly int[] dirs = {-1, 0, 1, 0, -1}; + private char[][] board; + private int m; + private int n; + + public void Solve(char[][] board) { + m = board.Length; + n = board[0].Length; + this.board = board; + + for (int i = 0; i < m; ++i) { + Dfs(i, 0); + Dfs(i, n - 1); + } + for (int j = 0; j < n; ++j) { + Dfs(0, j); + Dfs(m - 1, j); + } + + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (board[i][j] == '.') { + board[i][j] = 'O'; + } else if (board[i][j] == 'O') { + board[i][j] = 'X'; + } + } + } + } + + private void Dfs(int i, int j) { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O') { + return; + } + board[i][j] = '.'; + for (int k = 0; k < 4; ++k) { + Dfs(i + dirs[k], j + dirs[k + 1]); + } + } } \ No newline at end of file diff --git a/solution/0100-0199/0130.Surrounded Regions/Solution.go b/solution/0100-0199/0130.Surrounded Regions/Solution.go index d13690b5fe2e4..e4e29d1292a3f 100644 --- a/solution/0100-0199/0130.Surrounded Regions/Solution.go +++ b/solution/0100-0199/0130.Surrounded Regions/Solution.go @@ -1,28 +1,29 @@ func solve(board [][]byte) { m, n := len(board), len(board[0]) + dirs := [5]int{-1, 0, 1, 0, -1} var dfs func(i, j int) dfs = func(i, j int) { + if i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O' { + return + } board[i][j] = '.' - dirs := []int{-1, 0, 1, 0, -1} for k := 0; k < 4; k++ { - x, y := i+dirs[k], j+dirs[k+1] - if x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O' { - dfs(x, y) - } + dfs(i+dirs[k], j+dirs[k+1]) } } for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - if (i == 0 || i == m-1 || j == 0 || j == n-1) && board[i][j] == 'O' { - dfs(i, j) - } - } + dfs(i, 0) + dfs(i, n-1) } - for i := 0; i < m; i++ { - for j := 0; j < n; j++ { - if board[i][j] == '.' { + for j := 0; j < n; j++ { + dfs(0, j) + dfs(m-1, j) + } + for i, row := range board { + for j, c := range row { + if c == '.' { board[i][j] = 'O' - } else if board[i][j] == 'O' { + } else if c == 'O' { board[i][j] = 'X' } } diff --git a/solution/0100-0199/0130.Surrounded Regions/Solution.java b/solution/0100-0199/0130.Surrounded Regions/Solution.java index acb56f46e2181..16cf734717610 100644 --- a/solution/0100-0199/0130.Surrounded Regions/Solution.java +++ b/solution/0100-0199/0130.Surrounded Regions/Solution.java @@ -1,4 +1,5 @@ class Solution { + private final int[] dirs = {-1, 0, 1, 0, -1}; private char[][] board; private int m; private int n; @@ -8,11 +9,12 @@ public void solve(char[][] board) { n = board[0].length; this.board = board; for (int i = 0; i < m; ++i) { - for (int j = 0; j < n; ++j) { - if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && board[i][j] == 'O') { - dfs(i, j); - } - } + dfs(i, 0); + dfs(i, n - 1); + } + for (int j = 0; j < n; ++j) { + dfs(0, j); + dfs(m - 1, j); } for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { @@ -26,14 +28,12 @@ public void solve(char[][] board) { } private void dfs(int i, int j) { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O') { + return; + } board[i][j] = '.'; - int[] dirs = {-1, 0, 1, 0, -1}; for (int k = 0; k < 4; ++k) { - int x = i + dirs[k]; - int y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') { - dfs(x, y); - } + dfs(i + dirs[k], j + dirs[k + 1]); } } } \ No newline at end of file diff --git a/solution/0100-0199/0130.Surrounded Regions/Solution.py b/solution/0100-0199/0130.Surrounded Regions/Solution.py index dd8ecf05c5f58..a496d7c93342b 100644 --- a/solution/0100-0199/0130.Surrounded Regions/Solution.py +++ b/solution/0100-0199/0130.Surrounded Regions/Solution.py @@ -1,26 +1,22 @@ class Solution: def solve(self, board: List[List[str]]) -> None: - """ - Do not return anything, modify board in-place instead. - """ - - def dfs(i, j): - board[i][j] = '.' - for a, b in [[0, -1], [0, 1], [1, 0], [-1, 0]]: - x, y = i + a, j + b - if 0 <= x < m and 0 <= y < n and board[x][y] == 'O': - dfs(x, y) + def dfs(i: int, j: int): + if not (0 <= i < m and 0 <= j < n and board[i][j] == "O"): + return + board[i][j] = "." + for a, b in pairwise((-1, 0, 1, 0, -1)): + dfs(i + a, j + b) m, n = len(board), len(board[0]) for i in range(m): - for j in range(n): - if board[i][j] == 'O' and ( - i == 0 or i == m - 1 or j == 0 or j == n - 1 - ): - dfs(i, j) + dfs(i, 0) + dfs(i, n - 1) + for j in range(n): + dfs(0, j) + dfs(m - 1, j) for i in range(m): for j in range(n): - if board[i][j] == 'O': - board[i][j] = 'X' - elif board[i][j] == '.': - board[i][j] = 'O' + if board[i][j] == ".": + board[i][j] = "O" + elif board[i][j] == "O": + board[i][j] = "X" diff --git a/solution/0100-0199/0130.Surrounded Regions/Solution.rs b/solution/0100-0199/0130.Surrounded Regions/Solution.rs index bc6b8dd5e7adf..3ba59cf346749 100644 --- a/solution/0100-0199/0130.Surrounded Regions/Solution.rs +++ b/solution/0100-0199/0130.Surrounded Regions/Solution.rs @@ -1,41 +1,48 @@ impl Solution { - fn dfs(i: usize, j: usize, mark: char, vis: &mut Vec>, board: &mut Vec>) { - if vis[i][j] || board[i][j] != mark { - return; - } - vis[i][j] = true; - if i > 0 { - Self::dfs(i - 1, j, mark, vis, board); - } - if i < vis.len() - 1 { - Self::dfs(i + 1, j, mark, vis, board); - } - if j > 0 { - Self::dfs(i, j - 1, mark, vis, board); - } - if j < vis[0].len() - 1 { - Self::dfs(i, j + 1, mark, vis, board); - } - } - pub fn solve(board: &mut Vec>) { let m = board.len(); let n = board[0].len(); - let mut vis = vec![vec![false; n]; m]; + let dirs = vec![-1, 0, 1, 0, -1]; + + fn dfs( + board: &mut Vec>, + i: usize, + j: usize, + dirs: &Vec, + m: usize, + n: usize + ) { + if i >= 0 && i < m && j >= 0 && j < n && board[i][j] == 'O' { + board[i][j] = '.'; + for k in 0..4 { + dfs( + board, + ((i as i32) + dirs[k]) as usize, + ((j as i32) + dirs[k + 1]) as usize, + dirs, + m, + n + ); + } + } + } + for i in 0..m { - Self::dfs(i, 0, board[i][0], &mut vis, board); - Self::dfs(i, n - 1, board[i][n - 1], &mut vis, board); + dfs(board, i, 0, &dirs, m, n); + dfs(board, i, n - 1, &dirs, m, n); } - for i in 0..n { - Self::dfs(0, i, board[0][i], &mut vis, board); - Self::dfs(m - 1, i, board[m - 1][i], &mut vis, board); + for j in 0..n { + dfs(board, 0, j, &dirs, m, n); + dfs(board, m - 1, j, &dirs, m, n); } + for i in 0..m { for j in 0..n { - if vis[i][j] { - continue; + if board[i][j] == '.' { + board[i][j] = 'O'; + } else if board[i][j] == 'O' { + board[i][j] = 'X'; } - board[i][j] = 'X'; } } } diff --git a/solution/0100-0199/0130.Surrounded Regions/Solution.ts b/solution/0100-0199/0130.Surrounded Regions/Solution.ts index 361f5b2280c38..4f8c496b0133f 100644 --- a/solution/0100-0199/0130.Surrounded Regions/Solution.ts +++ b/solution/0100-0199/0130.Surrounded Regions/Solution.ts @@ -1,32 +1,29 @@ -/** - Do not return anything, modify board in-place instead. - */ function solve(board: string[][]): void { - function dfs(i, j) { + const m = board.length; + const n = board[0].length; + const dirs: number[] = [-1, 0, 1, 0, -1]; + const dfs = (i: number, j: number): void => { + if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] !== 'O') { + return; + } board[i][j] = '.'; - const dirs = [-1, 0, 1, 0, -1]; for (let k = 0; k < 4; ++k) { - const x = i + dirs[k]; - const y = j + dirs[k + 1]; - if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') { - dfs(x, y); - } + dfs(i + dirs[k], j + dirs[k + 1]); } - } - const m = board.length; - const n = board[0].length; + }; for (let i = 0; i < m; ++i) { - for (let j = 0; j < n; ++j) { - if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && board[i][j] == 'O') { - dfs(i, j); - } - } + dfs(i, 0); + dfs(i, n - 1); + } + for (let j = 0; j < n; ++j) { + dfs(0, j); + dfs(m - 1, j); } for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - if (board[i][j] == '.') { + if (board[i][j] === '.') { board[i][j] = 'O'; - } else if (board[i][j] == 'O') { + } else if (board[i][j] === 'O') { board[i][j] = 'X'; } } diff --git a/solution/0100-0199/0130.Surrounded Regions/Solution2.cpp b/solution/0100-0199/0130.Surrounded Regions/Solution2.cpp index 8661754713bce..3c0d92b9e4046 100644 --- a/solution/0100-0199/0130.Surrounded Regions/Solution2.cpp +++ b/solution/0100-0199/0130.Surrounded Regions/Solution2.cpp @@ -1,34 +1,36 @@ class Solution { public: - vector p; - void solve(vector>& board) { int m = board.size(), n = board[0].size(); - p.resize(m * n + 1); - for (int i = 0; i < p.size(); ++i) p[i] = i; - vector dirs = {-1, 0, 1, 0, -1}; + vector p(m * n + 1); + iota(p.begin(), p.end(), 0); + function find = [&](int x) { + return p[x] == x ? x : p[x] = find(p[x]); + }; + int dirs[5] = {-1, 0, 1, 0, -1}; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (board[i][j] == 'O') { - if (i == 0 || i == m - 1 || j == 0 || j == n - 1) + if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { p[find(i * n + j)] = find(m * n); - else { + } else { for (int k = 0; k < 4; ++k) { - int x = i + dirs[k], y = j + dirs[k + 1]; - if (board[x][y] == 'O') p[find(x * n + y)] = find(i * n + j); + int x = i + dirs[k]; + int y = j + dirs[k + 1]; + if (board[x][y] == 'O') { + p[find(x * n + y)] = find(i * n + j); + } } } } } } - for (int i = 0; i < m; ++i) - for (int j = 0; j < n; ++j) - if (board[i][j] == 'O' && find(i * n + j) != find(m * n)) + for (int i = 0; i < m; ++i) { + for (int j = 0; j < n; ++j) { + if (board[i][j] == 'O' && find(i * n + j) != find(m * n)) { board[i][j] = 'X'; - } - - int find(int x) { - if (p[x] != x) p[x] = find(p[x]); - return p[x]; + } + } + } } }; \ No newline at end of file diff --git a/solution/0100-0199/0130.Surrounded Regions/Solution2.go b/solution/0100-0199/0130.Surrounded Regions/Solution2.go index d4c0bead9475e..f3c2d3757e6a1 100644 --- a/solution/0100-0199/0130.Surrounded Regions/Solution2.go +++ b/solution/0100-0199/0130.Surrounded Regions/Solution2.go @@ -11,7 +11,7 @@ func solve(board [][]byte) { } return p[x] } - dirs := []int{-1, 0, 1, 0, -1} + dirs := [5]int{-1, 0, 1, 0, -1} for i := 0; i < m; i++ { for j := 0; j < n; j++ { if board[i][j] == 'O' { diff --git a/solution/0100-0199/0130.Surrounded Regions/Solution2.py b/solution/0100-0199/0130.Surrounded Regions/Solution2.py index 1a9c792a2ac11..ab6b12cf7bd7b 100644 --- a/solution/0100-0199/0130.Surrounded Regions/Solution2.py +++ b/solution/0100-0199/0130.Surrounded Regions/Solution2.py @@ -1,10 +1,6 @@ class Solution: def solve(self, board: List[List[str]]) -> None: - """ - Do not return anything, modify board in-place instead. - """ - - def find(x): + def find(x: int) -> int: if p[x] != x: p[x] = find(p[x]) return p[x] @@ -13,15 +9,15 @@ def find(x): p = list(range(m * n + 1)) for i in range(m): for j in range(n): - if board[i][j] == 'O': - if i == 0 or i == m - 1 or j == 0 or j == n - 1: + if board[i][j] == "O": + if i in (0, m - 1) or j in (0, n - 1): p[find(i * n + j)] = find(m * n) else: - for a, b in [(-1, 0), (1, 0), (0, -1), (0, 1)]: + for a, b in pairwise((-1, 0, 1, 0, -1)): x, y = i + a, j + b - if board[x][y] == 'O': + if board[x][y] == "O": p[find(x * n + y)] = find(i * n + j) for i in range(m): for j in range(n): - if board[i][j] == 'O' and find(i * n + j) != find(m * n): - board[i][j] = 'X' + if board[i][j] == "O" and find(i * n + j) != find(m * n): + board[i][j] = "X" diff --git a/solution/0100-0199/0130.Surrounded Regions/Solution2.ts b/solution/0100-0199/0130.Surrounded Regions/Solution2.ts index d2bf9f4c1d73c..7c9cf0767da06 100644 --- a/solution/0100-0199/0130.Surrounded Regions/Solution2.ts +++ b/solution/0100-0199/0130.Surrounded Regions/Solution2.ts @@ -1,30 +1,25 @@ -/** - Do not return anything, modify board in-place instead. - */ function solve(board: string[][]): void { const m = board.length; const n = board[0].length; - let p = new Array(m * n + 1); - for (let i = 0; i < p.length; ++i) { - p[i] = i; - } - function find(x) { - if (p[x] != x) { + const p: number[] = Array(m * n + 1) + .fill(0) + .map((_, i) => i); + const dirs: number[] = [-1, 0, 1, 0, -1]; + const find = (x: number): number => { + if (p[x] !== x) { p[x] = find(p[x]); } return p[x]; - } - const dirs = [-1, 0, 1, 0, -1]; + }; for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - if (board[i][j] == 'O') { - if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { + if (board[i][j] === 'O') { + if (i === 0 || i === m - 1 || j === 0 || j === n - 1) { p[find(i * n + j)] = find(m * n); } else { for (let k = 0; k < 4; ++k) { - const x = i + dirs[k]; - const y = j + dirs[k + 1]; - if (board[x][y] == 'O') { + const [x, y] = [i + dirs[k], j + dirs[k + 1]]; + if (board[x][y] === 'O') { p[find(x * n + y)] = find(i * n + j); } } @@ -34,7 +29,7 @@ function solve(board: string[][]): void { } for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { - if (board[i][j] == 'O' && find(i * n + j) != find(m * n)) { + if (board[i][j] === 'O' && find(i * n + j) !== find(m * n)) { board[i][j] = 'X'; } }