publicintnumEnclaves(int[][] grid) { m = grid.length; n = grid[0].length; visited = newboolean[m][n]; for (inti=0; i < m; i++) { dfs(grid, i, 0); dfs(grid, i, n - 1); } for (intj=1; j < n - 1; j++) { dfs(grid, 0, j); dfs(grid, m - 1, j); } intenclaves=0; for (inti=1; i < m - 1; i++) { for (intj=1; j < n - 1; j++) { if (grid[i][j] == 1 && !visited[i][j]) { enclaves++; } } } return enclaves; }
publicvoiddfs(int[][] grid, int row, int col) { if (row < 0 || row >= m || col < 0 || col >= n || grid[row][col] == 0 || visited[row][col]) { return; } visited[row][col] = true; for (int[] dir : dirs) { dfs(grid, row + dir[0], col + dir[1]); } } }
publicintNumEnclaves(int[][] grid) { m = grid.Length; n = grid[0].Length; visited = newbool[m][]; for (int i = 0; i < m; i++) { visited[i] = newbool[n]; } for (int i = 0; i < m; i++) { DFS(grid, i, 0); DFS(grid, i, n - 1); } for (int j = 1; j < n - 1; j++) { DFS(grid, 0, j); DFS(grid, m - 1, j); } int enclaves = 0; for (int i = 1; i < m - 1; i++) { for (int j = 1; j < n - 1; j++) { if (grid[i][j] == 1 && !visited[i][j]) { enclaves++; } } } return enclaves; }
publicvoidDFS(int[][] grid, int row, int col) { if (row < 0 || row >= m || col < 0 || col >= n || grid[row][col] == 0 || visited[row][col]) { return; } visited[row][col] = true; foreach (int[] dir in dirs) { DFS(grid, row + dir[0], col + dir[1]); } } }
intnumEnclaves(vector<vector<int>>& grid){ this->m = grid.size(); this->n = grid[0].size(); this->visited = vector<vector<bool>>(m, vector<bool>(n, false)); for (int i = 0; i < m; i++) { dfs(grid, i, 0); dfs(grid, i, n - 1); } for (int j = 1; j < n - 1; j++) { dfs(grid, 0, j); dfs(grid, m - 1, j); } int enclaves = 0; for (int i = 1; i < m - 1; i++) { for (int j = 1; j < n - 1; j++) { if (grid[i][j] == 1 && !visited[i][j]) { enclaves++; } } } return enclaves; }
voiddfs(const vector<vector<int>> & grid, int row, int col){ if (row < 0 || row >= m || col < 0 || col >= n || grid[row][col] == 0 || visited[row][col]) { return; } visited[row][col] = true; for (auto & dir : dirs) { dfs(grid, row + dir[0], col + dir[1]); } } private: int m, n; vector<vector<bool>> visited; };
voiddfs(constint** grid, int m, int n, uint8_t** visited, int row, int col) { if (row < 0 || row >= m || col < 0 || col >= n || grid[row][col] == 0 || visited[row][col]) { return; } visited[row][col] = 1; for (int i = 0; i < 4 ; i++) { dfs(grid, m, n, visited, row + dirs[i][0], col + dirs[i][1]); } }
intnumEnclaves(int** grid, int gridSize, int* gridColSize) { int m = gridSize, n = gridColSize[0]; uint8_t ** visited = (uint8_t **)malloc(sizeof(uint8_t *) * m); for (int i = 0; i < m; i++) { visited[i] = (uint8_t *)malloc(sizeof(uint8_t) * n); memset(visited[i], 0, sizeof(uint8_t) * n); } for (int i = 0; i < m; i++) { dfs(grid, m, n, visited, i, 0); dfs(grid, m, n, visited, i, n - 1); } for (int j = 1; j < n - 1; j++) { dfs(grid, m, n, visited, 0, j); dfs(grid, m, n, visited, m - 1, j); } int enclaves = 0; for (int i = 1; i < m - 1; i++) { for (int j = 1; j < n - 1; j++) { if (grid[i][j] == 1 && !visited[i][j]) { enclaves++; } } } for (int i = 0; i < m; i++) { free(visited[i]); } free(visited); return enclaves; }
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution: defnumEnclaves(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) vis = [[False] * n for _ inrange(m)]
defdfs(r: int, c: int) -> None: if r < 0or r >= m or c < 0or c >= n or grid[r][c] == 0or vis[r][c]: return vis[r][c] = True for x, y in ((r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)): dfs(x, y)
for i inrange(m): dfs(i, 0) dfs(i, n - 1) for j inrange(1, n - 1): dfs(0, j) dfs(m - 1, j) returnsum(grid[i][j] andnot vis[i][j] for i inrange(1, m - 1) for j inrange(1, n - 1))
var dirs = []struct{ x, y int }{ {-1, 0}, {1, 0}, {0, -1}, {0, 1} }
funcnumEnclaves(grid [][]int) (ans int) { m, n := len(grid), len(grid[0]) vis := make([][]bool, m) for i := range vis { vis[i] = make([]bool, n) } var dfs func(int, int) dfs = func(r, c int) { if r < 0 || r >= m || c < 0 || c >= n || grid[r][c] == 0 || vis[r][c] { return } vis[r][c] = true for _, d := range dirs { dfs(r+d.x, c+d.y) } } for i := range grid { dfs(i, 0) dfs(i, n-1) } for j := 1; j < n-1; j++ { dfs(0, j) dfs(m-1, j) } for i := 1; i < m-1; i++ { for j := 1; j < n-1; j++ { if grid[i][j] == 1 && !vis[i][j] { ans++ } } } return }
var numEnclaves = function(grid) { const dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]; const m = grid.length; const n = grid[0].length; const visited = newArray(m).fill(0).map(() =>newArray(n).fill(false));
constdfs = (grid, row, col) => { if (row < 0 || row >= m || col < 0 || col >= n || grid[row][col] == 0 || visited[row][col]) { return; } visited[row][col] = true; for (const dir of dirs) { dfs(grid, row + dir[0], col + dir[1]); } };
for (let i = 0; i < m; i++) { dfs(grid, i, 0); dfs(grid, i, n - 1); } for (let j = 1; j < n - 1; j++) { dfs(grid, 0, j); dfs(grid, m - 1, j); } let enclaves = 0; for (let i = 1; i < m - 1; i++) { for (let j = 1; j < n - 1; j++) { if (grid[i][j] === 1 && !visited[i][j]) { enclaves++; } } } return enclaves; }
复杂度分析
时间复杂度:O(mn),其中 m 和 n 分别是网格 grid 的行数和列数。深度优先搜索最多访问每个单元格一次,需要 O(mn) 的时间,遍历网格统计飞地的数量也需要 O(mn) 的时间。
空间复杂度:O(mn),其中 m 和 n 分别是网格 grid 的行数和列数。空间复杂度主要取决于 visited 数组和递归调用栈空间,空间复杂度是 O(mn)。
classSolution: defnumEnclaves(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) vis = [[False] * n for _ inrange(m)] q = deque() for i, row inenumerate(grid): if row[0]: vis[i][0] = True q.append((i, 0)) if row[n - 1]: vis[i][n - 1] = True q.append((i, n - 1)) for j inrange(1, n - 1): if grid[0][j]: vis[0][j] = True q.append((0, j)) if grid[m - 1][j]: vis[m - 1][j] = True q.append((m - 1, j)) while q: r, c = q.popleft() for x, y in ((r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)): if0 <= x < m and0 <= y < n and grid[x][y] andnot vis[x][y]: vis[x][y] = True q.append((x, y)) returnsum(grid[i][j] andnot vis[i][j] for i inrange(1, m - 1) for j inrange(1, n - 1))
publicclassSolution { publicintNumEnclaves(int[][] grid) { int m = grid.Length, n = grid[0].Length; UnionFind uf = new UnionFind(grid); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == 1) { int index = i * n + j; if (j + 1 < n && grid[i][j + 1] == 1) { uf.Union(index, index + 1); } if (i + 1 < m && grid[i + 1][j] == 1) { uf.Union(index, index + n); } } } } int enclaves = 0; for (int i = 1; i < m - 1; i++) { for (int j = 1; j < n - 1; j++) { if (grid[i][j] == 1 && !uf.IsOnEdge(i * n + j)) { enclaves++; } } } return enclaves; } }
publicUnionFind(int[][] grid) { int m = grid.Length, n = grid[0].Length; parent = newint[m * n]; onEdge = newbool[m * n]; rank = newint[m * n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == 1) { int index = i * n + j; parent[index] = index; if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { onEdge[index] = true; } } } } }
classSolution { public: intnumEnclaves(vector<vector<int>>& grid){ int m = grid.size(), n = grid[0].size(); UnionFind uf(grid); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == 1) { int index = i * n + j; if (j + 1 < n && grid[i][j + 1] == 1) { uf.uni(index, index + 1); } if (i + 1 < m && grid[i + 1][j] == 1) { uf.uni(index, index + n); } } } } int enclaves = 0; for (int i = 1; i < m - 1; i++) { for (int j = 1; j < n - 1; j++) { if (grid[i][j] == 1 && !uf.isOnEdge(i * n + j)) { enclaves++; } } } return enclaves; } };
boolisOnEdge(UnionFind * uf, int i) { return uf->onEdge[find(uf, i)]; }
intnumEnclaves(int** grid, int gridSize, int* gridColSize){ int m = gridSize, n = gridColSize[0]; UnionFind * uf = (UnionFind *)malloc(sizeof(UnionFind)); initUnionFind(uf, grid, gridSize, gridColSize); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == 1) { int index = i * n + j; if (j + 1 < n && grid[i][j + 1] == 1) { uni(uf, index, index + 1); } if (i + 1 < m && grid[i + 1][j] == 1) { uni(uf, index, index + n); } } } } int enclaves = 0; for (int i = 1; i < m - 1; i++) { for (int j = 1; j < n - 1; j++) { if (grid[i][j] == 1 && !isOnEdge(uf, i * n + j)) { enclaves++; } } } freeUnionFind(uf); free(uf); return enclaves; }
classUnionFind: def__init__(self, grid: List[List[int]]): m, n = len(grid), len(grid[0]) self.parent = [0] * (m * n) self.rank = [0] * (m * n) self.onEdge = [False] * (m * n) for i, row inenumerate(grid): for j, v inenumerate(row): if v: idx = i * n + j self.parent[idx] = idx if i == 0or i == m - 1or j == 0or j == n - 1: self.onEdge[idx] = True
defmerge(self, x: int, y: int) -> None: x, y = self.find(x), self.find(y) if x == y: return if self.rank[x] > self.rank[y]: self.parent[y] = x self.onEdge[x] |= self.onEdge[y] elif self.rank[x] < self.rank[y]: self.parent[x] = y self.onEdge[y] |= self.onEdge[x] else: self.parent[y] = x self.onEdge[x] |= self.onEdge[y] self.rank[x] += 1
classSolution: defnumEnclaves(self, grid: List[List[int]]) -> int: uf = UnionFind(grid) m, n = len(grid), len(grid[0]) for i, row inenumerate(grid): for j, v inenumerate(row): if v: idx = i * n + j if j + 1 < n and grid[i][j + 1]: uf.merge(idx, idx + 1) if i + 1 < m and grid[i + 1][j]: uf.merge(idx, idx + n) returnsum(grid[i][j] andnot uf.onEdge[uf.find(i * n + j)] for i inrange(1, m - 1) for j inrange(1, n - 1))
funcnewUnionFind(grid [][]int) unionFind { m, n := len(grid), len(grid[0]) parent := make([]int, m*n) rank := make([]int, m*n) onEdge := make([]bool, m*n) for i, row := range grid { for j, v := range row { if v == 1 { idx := i*n + j parent[idx] = idx if i == 0 || i == m-1 || j == 0 || j == n-1 { onEdge[idx] = true } } } } return unionFind{parent, rank, onEdge} }
func(uf unionFind) find(x int) int { if uf.parent[x] != x { uf.parent[x] = uf.find(uf.parent[x]) } return uf.parent[x] }
func(uf unionFind) merge(x, y int) { x, y = uf.find(x), uf.find(y) if x == y { return } if uf.rank[x] > uf.rank[y] { uf.parent[y] = x uf.onEdge[x] = uf.onEdge[x] || uf.onEdge[y] } elseif uf.rank[x] < uf.rank[y] { uf.parent[x] = y uf.onEdge[y] = uf.onEdge[y] || uf.onEdge[x] } else { uf.parent[y] = x uf.onEdge[x] = uf.onEdge[x] || uf.onEdge[y] uf.rank[x]++ } }
funcnumEnclaves(grid [][]int) (ans int) { uf := newUnionFind(grid) m, n := len(grid), len(grid[0]) for i, row := range grid { for j, v := range row { if v == 1 { idx := i*n + j if j+1 < n && grid[i][j+1] == 1 { uf.merge(idx, idx+1) } if i+1 < m && grid[i+1][j] == 1 { uf.merge(idx, idx+n) } } } } for i := 1; i < m-1; i++ { for j := 1; j < n-1; j++ { if grid[i][j] == 1 && !uf.onEdge[uf.find(i*n+j)] { ans++ } } } return }
var numEnclaves = function(grid) { const m = grid.length, n = grid[0].length; const uf = newUnionFind(grid); for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { if (grid[i][j] === 1) { const index = i * n + j; if (j + 1 < n && grid[i][j + 1] === 1) { uf.union(index, index + 1); } if (i + 1 < m && grid[i + 1][j] === 1) { uf.union(index, index + n); } } } } let enclaves = 0; for (let i = 1; i < m - 1; i++) { for (let j = 1; j < n - 1; j++) { if (grid[i][j] === 1 && !uf.isOnEdge(i * n + j)) { enclaves++; } } } return enclaves; }
classUnionFind { constructor(grid) { const m = grid.length, n = grid[0].length; this.parent = newArray(m * n).fill(0); this.onEdge = newArray(m * n).fill(false); this.rank = newArray(m * n).fill(0); for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { if (grid[i][j] === 1) { const index = i * n + j; this.parent[index] = index; if (i === 0 || i === m - 1 || j === 0 || j === n - 1) { this.onEdge[index] = true; } } } } }