1254.Number of Closed Islands === ###### tags: `Medium`,`Array`,`DFS`,`BFS`,`Matrix` [1254. Number of Closed Islands](https://leetcode.com/problems/number-of-closed-islands/) ### 題目描述 Given a 2D `grid` consists of `0s` (land) and `1s` (water). An island is a maximal 4-directionally connected group of `0s` and a *closed island* is an island **totally** (all left, top, right, bottom) surrounded by `1s`. Return the number *of closed islands*. ### 範例 **Example 1:** ![](https://assets.leetcode.com/uploads/2019/10/31/sample_3_1610.png) ``` Input: grid = [[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],[1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]] Output: 2 Explanation: Islands in gray are closed because they are completely surrounded by water (group of 1s). ``` **Example 2:** ![](https://assets.leetcode.com/uploads/2019/10/31/sample_4_1610.png) ``` Input: grid = [[0,0,1,0,0],[0,1,0,1,0],[0,1,1,1,0]] Output: 1 ``` **Example 3:** ``` Input: grid = [[1,1,1,1,1,1,1], [1,0,0,0,0,0,1], [1,0,1,1,1,0,1], [1,0,1,0,1,0,1], [1,0,1,1,1,0,1], [1,0,0,0,0,0,1], [1,1,1,1,1,1,1]] Output: 2 ``` **Constraints**: * 1 <= `grid.length`, `grid[0].length` <= 100 * 0 <= `grid[i][j]` <=1 ### 解答 #### python ```python= class Solution: def closedIsland(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) def dfs(x, y): if 0 <= x < m and 0 <= y < n and grid[x][y] == 0: grid[x][y] = 1 dfs(x-1, y) dfs(x+1, y) dfs(x, y-1) dfs(x, y+1) for x in range(m): for y in range(n): if (x in (0, m - 1) or y in (0, n - 1)) and grid[x][y] == 0: dfs(x, y) res = 0 for x in range(m): for y in range(n): if grid[x][y] == 0: dfs(x, y) res += 1 return res ``` > [name=Ron Chen][time=Thr, Apr 6, 2023] #### Javascript ```javascript= function closedIsland(grid) { let result = 0; const n = grid.length; const m = grid[0].length; const visited = new Array(n).fill(false).map(() => new Array(m).fill(false)); for (let i = 0; i < n; i++) { for (let j = 0; j < m; j++) { if (grid[i][j] === 0) { if (visited[i][j]) continue; const { water, isClosed } = getWater(grid, [i, j]); if (isClosed) result++; for (const w of water) { visited[w[0]][w[1]] = true; } } } } return result; } function getWater(grid, point) { const n = grid.length; const m = grid[0].length; const isInBounds = (x, y) => x < n && x >= 0 && y < m && y >= 0; const isEdge = (x, y) => x === n - 1 || x === 0 || y === 0 || y === m - 1; const visited = new Array(n).fill(false).map(() => new Array(m).fill(false)); const water = [point]; const stack = [point]; visited[point[0]][point[1]] = true; let isClosed = true; while (stack.length) { const [x, y] = stack.pop(); if (isEdge(x, y)) isClosed = false; const neighbors = [ [x, y - 1], [x, y + 1], [x - 1, y], [x + 1, y], ]; for (const neighbor of neighbors) { const [nx, ny] = neighbor; if (isInBounds(nx, ny) && !visited[nx][ny]) { if (grid[nx][ny] === 0) { stack.push(neighbor); water.push(neighbor); visited[nx][ny] = true; } } } } return { water, isClosed }; } ``` > 想說跟圍棋數氣差不多意思,也用同個方法寫 > [name=Marsgoat][time=Thr, Apr 6, 2023] ```javascript= function closedIsland2(grid) { let result = 0; const n = grid.length; const m = grid[0].length; for (let i = 0; i < n; i++) { for (let j = 0; j < m; j++) { if (grid[i][j] === 0) { if (isClosed([i, j])) result++; } } } return result; function isClosed(point) { const isInBounds = (x, y) => x < n && x >= 0 && y < m && y >= 0; const isEdge = (x, y) => x === n - 1 || x === 0 || y === 0 || y === m - 1; const stack = [point]; let isClosed = true; while (stack.length) { const [x, y] = stack.pop(); if (isEdge(x, y)) isClosed = false; grid[x][y] = 1; const neighbors = [ [x, y - 1], [x, y + 1], [x - 1, y], [x + 1, y], ]; for (const neighbor of neighbors) { const [nx, ny] = neighbor; if (isInBounds(nx, ny)) { if (grid[nx][ny] === 0) { stack.push(neighbor); } } } } return isClosed; } } ``` > 前面的版本有點傻,根本不需要計算相連的水的數量,這樣改快了不少。 > [name=Marsgoat][time=Thr, Apr 6, 2023] ### Reference [回到題目列表](https://hackmd.io/@Marsgoat/leetcode_every_day)