classSolution: defshortestBridge(self, grid: List[List[int]]) -> int: n = len(grid) for i, row inenumerate(grid): for j, v inenumerate(row): if v != 1: continue island = [] grid[i][j] = -1 q = deque([(i, j)]) while q: x, y = q.popleft() island.append((x, y)) for nx, ny in (x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1): if0 <= nx < n and0 <= ny < n and grid[nx][ny] == 1: grid[nx][ny] = -1 q.append((nx, ny))
step = 0 q = island whileTrue: tmp = q q = [] for x, y in tmp: for nx, ny in (x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1): if0 <= nx < n and0 <= ny < n: if grid[nx][ny] == 1: return step if grid[nx][ny] == 0: grid[nx][ny] = -1 q.append((nx, ny)) step += 1
for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == 1) { qu.emplace(i, j); grid[i][j] = -1; while (!qu.empty()) { auto [x, y] = qu.front(); qu.pop(); island.emplace_back(x, y); for (int k = 0; k < 4; k++) { int nx = x + dirs[k][0]; int ny = y + dirs[k][1]; if (nx >= 0 && ny >= 0 && nx < n && ny < n && grid[nx][ny] == 1) { qu.emplace(nx, ny); grid[nx][ny] = -1; } } } for (auto &&[x, y] : island) { qu.emplace(x, y); } int step = 0; while (!qu.empty()) { int sz = qu.size(); for (int i = 0; i < sz; i++) { auto [x, y] = qu.front(); qu.pop(); for (int k = 0; k < 4; k++) { int nx = x + dirs[k][0]; int ny = y + dirs[k][1]; if (nx >= 0 && ny >= 0 && nx < n && ny < n) { if (grid[nx][ny] == 0) { qu.emplace(nx, ny); grid[nx][ny] = -1; } elseif (grid[nx][ny] == 1) { return step; } } } } step++; } } } } return0; } };
publicclassSolution { publicintShortestBridge(int[][] grid) { int n = grid.Length; int[][] dirs = {newint[]{-1, 0}, newint[]{1, 0}, newint[]{0, 1}, newint[]{0, -1}}; IList<Tuple<int, int>> island = new List<Tuple<int, int>>(); Queue<Tuple<int, int>> queue = new Queue<Tuple<int, int>>();
for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == 1) { queue.Enqueue(new Tuple<int, int>(i, j)); grid[i][j] = -1; while (queue.Count > 0) { Tuple<int, int> cell = queue.Dequeue(); int x = cell.Item1, y = cell.Item2; island.Add(cell); for (int k = 0; k < 4; k++) { int nx = x + dirs[k][0]; int ny = y + dirs[k][1]; if (nx >= 0 && ny >= 0 && nx < n && ny < n && grid[nx][ny] == 1) { queue.Enqueue(new Tuple<int, int>(nx, ny)); grid[nx][ny] = -1; } } } foreach (Tuple<int, int> cell in island) { queue.Enqueue(cell); } int step = 0; while (queue.Count > 0) { int sz = queue.Count; for (int k = 0; k < sz; k++) { Tuple<int, int> cell = queue.Dequeue(); int x = cell.Item1, y = cell.Item2; for (int d = 0; d < 4; d++) { int nx = x + dirs[d][0]; int ny = y + dirs[d][1]; if (nx >= 0 && ny >= 0 && nx < n && ny < n) { if (grid[nx][ny] == 0) { queue.Enqueue(new Tuple<int, int>(nx, ny)); grid[nx][ny] = -1; } elseif (grid[nx][ny] == 1) { return step; } } } } step++; } } } } return0; } }
intshortestBridge(int** grid, int gridSize, int* gridColSize) { int n = gridSize; int dirs[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; int *island = (int *)malloc(sizeof(int) * n * n); int *queue = (int *)malloc(sizeof(int) * n * n); int head = 0, tail = 0;
for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == 1) { queue[tail++] = i * n + j; grid[i][j] = -1; int islandSize = 0; while (head != tail) { int x = queue[head] / n; int y = queue[head] % n; island[islandSize++] = queue[head]; head++; for (int k = 0; k < 4; k++) { int nx = x + dirs[k][0]; int ny = y + dirs[k][1]; if (nx >= 0 && ny >= 0 && nx < n && ny < n && grid[nx][ny] == 1) { queue[tail++] = nx * n + ny; grid[nx][ny] = -1; } } } head = tail = 0; for (int i = 0; i < islandSize; i++) { queue[tail++] = island[i]; } int step = 0; while (head != tail) { int sz = tail - head; for (int i = 0; i < sz; i++) { int x = queue[head] / n; int y = queue[head] % n; head++; for (int k = 0; k < 4; k++) { int nx = x + dirs[k][0]; int ny = y + dirs[k][1]; if (nx >= 0 && ny >= 0 && nx < n && ny < n) { if (grid[nx][ny] == 0) { queue[tail++] = nx * n + ny; grid[nx][ny] = -1; } elseif (grid[nx][ny] == 1) { free(queue); free(island); return step; } } } } step++; } } } } return0; }
var shortestBridge = function(grid) { const n = grid.length; const dirs = [[-1, 0], [1, 0], [0, 1], [0, -1]]; const island = []; const queue = [];
for (let i = 0; i < n; i++) { for (let j = 0; j < n; j++) { if (grid[i][j] === 1) { queue.push([i, j]); grid[i][j] = -1; while (queue.length !== 0) { const cell = queue.shift(); let x = cell[0], y = cell[1]; island.push(cell); for (let k = 0; k < 4; k++) { let nx = x + dirs[k][0]; let ny = y + dirs[k][1]; if (nx >= 0 && ny >= 0 && nx < n && ny < n && grid[nx][ny] == 1) { queue.push([nx, ny]); grid[nx][ny] = -1; } } } for (const cell of island) { queue.push(cell); } let step = 0; while (queue.length !== 0) { const sz = queue.length; for (let k = 0; k < sz; k++) { const cell = queue.shift(); let x = cell[0], y = cell[1]; for (let d = 0; d < 4; d++) { let nx = x + dirs[d][0]; let ny = y + dirs[d][1]; if (nx >= 0 && ny >= 0 && nx < n && ny < n) { if (grid[nx][ny] === 0) { queue.push([nx, ny]); grid[nx][ny] = -1; } elseif (grid[nx][ny] === 1) { return step; } } } } step++; } } } } return0; };
funcshortestBridge(grid [][]int) (step int) { type pair struct{ x, y int } dirs := []pair{{-1, 0}, {1, 0}, {0, -1}, {0, 1}} n := len(grid) for i, row := range grid { for j, v := range row { if v != 1 { continue } island := []pair{} grid[i][j] = -1 q := []pair{{i, j}} forlen(q) > 0 { p := q[0] q = q[1:] island = append(island, p) for _, d := range dirs { x, y := p.x+d.x, p.y+d.y if0 <= x && x < n && 0 <= y && y < n && grid[x][y] == 1 { grid[x][y] = -1 q = append(q, pair{x, y}) } } }
q = island for { tmp := q q = nil for _, p := range tmp { for _, d := range dirs { x, y := p.x+d.x, p.y+d.y if0 <= x && x < n && 0 <= y && y < n { if grid[x][y] == 1 { return } if grid[x][y] == 0 { grid[x][y] = -1 q = append(q, pair{x, y}) } } } } step++ } } } return }
复杂度分析
时间复杂度:O(n^2),其中 n 表示 grid 的行数,grid 的行数与列数相等。我们只需遍历一遍矩阵即可完成访问两个不同的岛。
classSolution: defshortestBridge(self, grid: List[List[int]]) -> int: n = len(grid) for i, row inenumerate(grid): for j, v inenumerate(row): if v != 1: continue q = [] defdfs(x: int, y: int) -> None: grid[x][y] = -1 q.append((x, y)) for nx, ny in (x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1): if0 <= nx < n and0 <= ny < n and grid[nx][ny] == 1: dfs(nx, ny) dfs(i, j)
step = 0 whileTrue: tmp = q q = [] for x, y in tmp: for nx, ny in (x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1): if0 <= nx < n and0 <= ny < n: if grid[nx][ny] == 1: return step if grid[nx][ny] == 0: grid[nx][ny] = -1 q.append((nx, ny)) step += 1
voiddfs(int x, int y, int** grid, int n, int *queue, int *tail) { if (x < 0 || y < 0 || x >= n || y >= n || grid[x][y] != 1) { return; } queue[(*tail)++] = x * n + y; grid[x][y] = -1; dfs(x - 1, y, grid, n, queue, tail); dfs(x + 1, y, grid, n, queue, tail); dfs(x, y - 1, grid, n, queue, tail); dfs(x, y + 1, grid, n, queue, tail); }
intshortestBridge(int** grid, int gridSize, int* gridColSize) { int n = gridSize; int dirs[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == 1) { int *queue = (int *)malloc(sizeof(int) * n * n); int head = 0, tail = 0; dfs(i, j, grid, n, queue, &tail); int step = 0; while (head != tail) { int sz = tail - head; for (int i = 0; i < sz; i++) { int x = queue[head] / n; int y = queue[head] % n; head++; for (int k = 0; k < 4; k++) { int nx = x + dirs[k][0]; int ny = y + dirs[k][1]; if (nx >= 0 && ny >= 0 && nx < n && ny < n) { if (grid[nx][ny] == 0) { queue[tail++] = nx * n + ny; grid[nx][ny] = -1; } elseif (grid[nx][ny] == 1) { free(queue); return step; } } } } step++; } } } } return0; }
funcshortestBridge(grid [][]int) (step int) { type pair struct{ x, y int } dirs := []pair{{-1, 0}, {1, 0}, {0, -1}, {0, 1}} n := len(grid) for i, row := range grid { for j, v := range row { if v != 1 { continue } q := []pair{} var dfs func(int, int) dfs = func(i, j int) { grid[i][j] = -1 q = append(q, pair{i, j}) for _, d := range dirs { x, y := i+d.x, j+d.y if0 <= x && x < n && 0 <= y && y < n && grid[x][y] == 1 { dfs(x, y) } } } dfs(i, j)
for { tmp := q q = nil for _, p := range tmp { for _, d := range dirs { x, y := p.x+d.x, p.y+d.y if0 <= x && x < n && 0 <= y && y < n { if grid[x][y] == 1 { return } if grid[x][y] == 0 { grid[x][y] = -1 q = append(q, pair{x, y}) } } } } step++ } } } return }
复杂度分析
时间复杂度:O(n^2),其中 n 表示 grid 的行数,grid 的行数与列数相等。我们只需遍历一遍矩阵即可完成访问两个不同的岛。