leetcode:934. 最短的桥

这篇博客介绍了LeetCode上的第934题《最短的桥》的解决方案。作者详细解析了如何使用深度优先搜索(DFS)和广度优先搜索(BFS)算法来寻找两个岛屿之间的最短连接路径,将二维矩阵中的1(陆地)转换为2(已访问),并不断扩展直到找到另一岛屿。代码中包含了关键函数`shortestBridge`、`infect`和`bfs`的实现细节。
摘要由CSDN通过智能技术生成

题目来源

题目描述

在这里插入图片描述

class Solution {
public:
    int shortestBridge(vector<vector<int>>& grid) {

    }
};

题目解析(待研究)

为什么是这样?????

在这里插入图片描述

class Solution {
    // 当前来到m[i][j] , 总行数是N,总列数是M
    // m[i][j]感染出去(找到这一片岛所有的1),把每一个1的坐标,放入到int[] curs队列!
    // 1 (a,b) -> curs[index++] = (a * M + b)
    // 1 (c,d) -> curs[index++] = (c * M + d)
    // 设置距离record[a * M +b ] = 1
    int infect(vector<vector<int>>& grid, int i, int j, int N, int M,
            std::vector<int> &curs, int idx, std::vector<int> &record){
        if (i < 0 || i == N || j < 0 || j == M || grid[i][j] != 1) {
            return idx;
        }

        grid[i][j] = 2;
        int p = i * M + j;  //二维已经变成一维了, 1 (a,b) -> a * M + b
        record[p] = 1;
        // 收集到不同的1
        curs[idx++] = p;
        idx = infect(grid, i - 1, j, N, M, curs, idx, record);
        idx = infect(grid, i + 1, j, N, M, curs, idx, record);
        idx = infect(grid, i, j - 1, N, M, curs, idx, record);
        idx = infect(grid, i, j + 1, N, M, curs, idx, record);
        return idx;
    }

    int bfs(int N, int M, int all, int V,  std::vector<int> &curs,
            int size, std::vector<int> &nexts, std::vector<int> &record){
        int nexti = 0; // 我要生成的下一层队列成长到哪了?
        for (int i = 0; i < size; i++) {
            // curs[i] -> 一个位置
            int up = curs[i] < M ? -1 : curs[i] - M;
            int down = curs[i] + M >= all ? -1 : curs[i] + M;
            int left = curs[i] % M == 0 ? -1 : curs[i] - 1;
            int right = curs[i] % M == M - 1 ? -1 : curs[i] + 1;
            if (up != -1 && record[up] == 0) {
                record[up] = V;
                nexts[nexti++] = up;
            }
            if (down != -1 && record[down] == 0) {
                record[down] = V;
                nexts[nexti++] = down;
            }
            if (left != -1 && record[left] == 0) {
                record[left] = V;
                nexts[nexti++] = left;
            }
            if (right != -1 && record[right] == 0) {
                record[right] = V;
                nexts[nexti++] = right;
            }
        }
        return nexti;
    }
public:
    int shortestBridge(vector<vector<int>>& grid) {
        int N = grid.size(), M = grid[0].size();
        int all = N * M;
        int island = 0;
        std::vector<int> curs(all, 0);
        std::vector<int> nexts(all, 0);
        std::vector<std::vector<int>> records(2, std::vector<int>(all, 0));
        for (int i = 0; i < N; ++i) {
            for (int j = 0; j < M; ++j) {
                if (grid[i][j] == 1) { // 当前位置发现了1!
                    // 把这一片的1,都变成2,同时,抓上来了,这一片1组成的初始队列
                    // curs, 把这一片的1到自己的距离,都设置成1了,records
                    int queueSize = infect(grid, i, j, N, M, curs, 0, records[island]);
                    int V = 1;
                    while (queueSize != 0) {
                        V++;
                        // curs里面的点,上下左右,records[点]==0, nexts
                        queueSize = bfs(N, M, all, V, curs, queueSize, nexts, records[island]);
                        auto tmp = curs;
                        curs = nexts;
                        nexts = tmp;
                    }
                    island++;
                }
            }
        }

        int min = INT16_MAX;
        for (int i = 0; i < all; i++) {
            min = std::min(min, records[0][i] + records[1][i]);
        }
        return min - 3;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值