leetcode 934. 最短的桥

181 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情

934. 最短的桥

给你一个大小为 n x n 的二元矩阵 grid ,其中 1 表示陆地,0 表示水域。

 是由四面相连的 1 形成的一个最大组,即不会与非组内的任何其他 1 相连。grid 中 恰好存在两座岛 。

你可以将任意数量的 0 变为 1 ,以使两座岛连接起来,变成 一座岛 。

返回必须翻转的 0 的最小数目。

限制

  • n == grid.length == grid[i].length
  • 2 <= n <= 100
  • grid[i][j] 为 0 或 1
  • grid 中恰有两个岛

思路

题目给定我们一个二维化网格的图形,其中包含两个连通块,现在要求你计算两个连通块的最小距离

这道题是一道经典的多源bfs问题。

首先,让我们把这两个连通块的其中一个缩为一个点,然后你就可以发现,我们求的其实是给定起点到任意一个可达终点的最短距离。

那么,现在我们的起点可以是第一个图形的任意一个位置,于是把第一个图形的任意一个位置为起点开始对整个地图做一个bfs即可。

这就是多源bfs。

代码

use std::collections::{BTreeMap, BinaryHeap, HashMap, HashSet, VecDeque};
impl Solution {
    pub fn shortest_bridge(grid: Vec<Vec<i32>>) -> i32 {
        let ans = 0;
        let mut grid = grid;
        let (n, m) = (grid.len(), grid[0].len());
        let mut que = VecDeque::new();

        let xx = [0, 0, -1, 1];
        let yy = [1, -1, 0, 0];
        fn dfs(
            x: usize,
            y: usize,
            grid: &mut Vec<Vec<i32>>,
            que: &mut VecDeque<(usize, usize, i32)>,
        ) {
            let xx = [0, 0, -1, 1];
            let yy = [1, -1, 0, 0];
            grid[x][y] = 2;
            que.push_back((x, y, 0));
            let (n, m) = (grid.len(), grid[0].len());
            for i in 0..xx.len() {
                let dx = x as i32 + xx[i];
                let dy = y as i32 + yy[i];
                if dx < 0 || dy < 0 {
                    continue;
                }
                let dx = dx as usize;
                let dy = dy as usize;
                if dx >= n || dy >= m || grid[dx][dy] != 1 {
                    continue;
                }
                dfs(dx, dy, grid, que);
            }
        }
        let mut flag = 1;
        for i in 0..n {
            for j in 0..m {
                if grid[i][j] == 1 {
                    dfs(i, j, &mut grid, &mut que);
                    flag = 0;
                }
                if flag == 0 {
                    break;
                }
            }
            if flag == 0 {
                break;
            }
        }
        while let Some(t) = que.pop_front() {
            for i in 0..xx.len() {
                let dx = t.0 as i32 + xx[i];
                let dy = t.1 as i32 + yy[i];
                if dx < 0 || dy < 0 {
                    continue;
                }
                let dx = dx as usize;
                let dy = dy as usize;
                if dx >= n || dy >= m || grid[dx][dy] == 2 {
                    continue;
                }
                if (grid[dx][dy] == 1) {
                    return t.2;
                }
                grid[dx][dy] = 2;
                que.push_back((dx, dy, t.2 + 1));
            }
        }

        ans
    }
}