[LeetCode] 934、最短的桥

题目描述

在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组)现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。返回必须翻转的 0 的最小数目。

输入:[[0,1,0],[0,0,0],[0,0,1]]
输出:2

解题思路

算是比较好的一个题,直接想法是搜索:首先找到这两座岛,随后选择一座,将它不断向外延伸一圈,直到到达了另一座岛。在寻找这两座岛时,我们使用深度优先搜索。在向外延伸时,我们使用广度优先搜索。(DFS + BFS

  • DFS + BFS(推荐):dfs找到第一个岛修改原数组为2;将第二个岛入队列,进行宽搜,查找最小距离;

  • 两次BFS:第一个bfs,将其中一个岛渲染成2,并记录边界,只要某点四个连接点有一个为0,就是边界,添加进队列,用于第二个bfs的搜索。第二个bfs同时从各个边界出发,记录路径即可。(其实没有必要找边界,直接把第一座桥整体添加进队列就可以,如法一)

参考代码

class Solution { 
public:
    int dirR[4] = {-1, 0, 1, 0};
    int dirC[4] = {0, 1, 0, -1};
    queue<pair<int, int> > q;  // 也可以不用pair,定义一个结构体point
    
    int shortestBridge(vector<vector<int>> &A) {
        // dfs 查找两个岛,标记第一个岛为2(这里完全可以用i,j两个循环的方式写)
        for (int i = 0; i < A.size() * A[0].size(); i++) {
            if (A[i / A[0].size()][i % A[0].size()] == 1) {
                dfs(A, i / A[0].size(), i % A[0].size());
                break;
            }
        }

        int step = 0;
        // 第一个岛里面的所有点,向外扩展,记录层数,当遇到第二个岛的时候,返回层数   bfs
        while (!q.empty()) {
            int nums = q.size();  // 当前层的元素数
            while (nums--){
                auto tmp_pair = q.front(); q.pop();
                // 往四个方向 bfs
                for (int i = 0; i < 4; i++){
                    int r = tmp_pair.first + dirR[i];
                    int c = tmp_pair.second + dirC[i];
                    if (r < 0 || r >= A.size() || c < 0 || c >= A[0].size() || A[r][c] == 2) continue;
                    if (A[r][c] == 1) return step;  // 到达另一座桥
                    
                    A[r][c] = 2;  // 着色
                    q.push({r, c});
                }
            }
            step++;  // 相当于往外扩展了一圈之后,step才加加
        }

        return step;
    }
	
	// dfs(目的是把其中一座桥全部装进queue中,并着色为 2)
    void dfs(vector<vector<int>> &A, int i, int j) {
        q.push({i, j});  // 把其中一个桥全部装进queue
        A[i][j] = 2;     // 着色
        for (int d = 0; d < 4; d++) {
            int r = i + dirR[d];
            int c = j + dirC[d];
            if(r >= 0 && r < A.size() && c >= 0 && c < A[0].size() && A[r][c] == 1)
                dfs(A, r, c);
        }
    }
    
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值