Leetcode(934)——最短的桥

青云算法面试题干货-最短的桥-LeetCode第934题 问题:在一个由0、1组成的二维矩阵里,上下左右四个方向相连的1组成岛屿,而其他0的区域表示海洋。如果在矩阵里有两个岛屿,我们可以修建一座桥把两个岛屿连起来。修建桥的办法是把0翻转成上下左右四个方向相连的1。请问至少需要翻转多少个0才能将两个岛屿连起来?例如,在下面的二维矩阵中,我们只需要翻转坐标为(1, 1)和(2, 1)的两个0,或者坐标为(0, 2)和(1, 2)的两个0,就可以把两个岛屿连起... 阅读详情

Leetcode(934)——最短的桥

题目

在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 111 形成的一个最大组。)

现在,我们可以将 000 变为 111,以使两座岛连接起来,变成一座岛。

返回必须翻转的 000 的最小数目。(可以保证答案至少是 111 。)

示例 1:

输入:A = [[0,1],[1,0]]
输出:1

示例 2:

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

示例 3:

输入:A = [[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]
输出:1

提示:

  • 222 <= A.length == A[0].length <= 100100100
  • A[i][j] == 000 或 A[i][j] == 111

题解

方法一:DFS 修改值 + BFS

思路

​​  先找到其中一个岛屿中的一个点,然后进行 DFS\texttt{DFS}DFS 或 BFS\texttt{BFS}BFS,并把遍历到的所有值为 1 的点都变成 222,在遍历岛的过程中将 -1 岛的沿海一格全部加入队列。该队列就存储了 -1 岛的所有1格沿海。
​​  然后使用该队列进行 BFS\texttt{BFS}BFS,同时把遍历到的点 0 变成 -1,并且记录遍历的步数。当填海后要加入下一个点时,如果碰到的是 111 ,则返回 minminmin(最短桥的长度)。

​​  因为我们从 -1 岛的海岸线开始进行广度优先搜索(一层为一条海岸线),当它们到达了 1 岛中的任意一个位置时,增加的海岸线长度层数,即搜索层次就是答案。

注意:先导入再填海会导致出现两个的岛格可能会导入相同的海格,比如:[−1,0,−1][-1, 0, -1][−1,0,−1] 这会导致大量重复海格进入队列。

代码实现

Leetcode 官方题解:

class Solution {
public:
    vector<int> direction{-1, 0, 1, 0, -1};
    // 主函数
    int shortestBridge(vector<vector<int>>& grid) {
        int m = grid.size(), n = grid[0].size();
        queue<pair<int, int>> points;
        // dfs寻找第一个岛屿,并把1全部赋值为2
        bool flipped = false;
        for (int i = 0; i < m; ++i) {
            if (flipped) break;
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) {
                    dfs(points, grid, m, n, i, j);
                    flipped = true;
                    break;
                }
            }
        }
        // bfs寻找第二个岛屿,并把过程中经过的0赋值为2
        int x, y;
        int level = 0;
        while (!points.empty()){
            ++level;
            int n_points = points.size();
            while (n_points--) {
                auto [r, c] = points.front();
                points.pop();
                for (int k = 0; k < 4; ++k) {
                    x = r + direction[k], y = c + direction[k+1];
                    if (x >= 0 && y >= 0 && x < m && y < n) {
                        if (grid[x][y] == 2) {
                            continue;
                        }   
                        if (grid[x][y] == 1) {
                            return level;
                        }
                        points.push({x, y});
                        grid[x][y] = 2;
                    }
                }
            }
        }
        return 0;
    }
    // 辅函数
    void dfs(queue<pair<int, int>>& points, vector<vector<int>>& grid, int m, int n, int i, int j) {
        if (i < 0 || j < 0 || i == m || j == n || grid[i][j] == 2) {
            return;
        }
        if (grid[i][j] == 0) {
            points.push({i, j});
            return;
        }
        grid[i][j] = 2;
        dfs(points, grid, m, n, i - 1, j);
        dfs(points, grid, m, n, i + 1, j);
        dfs(points, grid, m, n, i, j - 1);
        dfs(points, grid, m, n, i, j + 1);
    }
};

我自己的:

class Solution {
    vector<int> direction{-1, 0, 1, 0, -1};
    int BFS(vector<vector<int>>& grid, queue<pair<int, int>>& q){
        int row, col, nextr, nextc, min = 0, times;
        while(!q.empty()){
            min++;  // 答案至少是 1
            times = q.size();
            while(times--){
                row = q.front().first;
                col = q.front().second;
                q.pop();
                grid[row][col] = -1;    // 填海
                for(int n = 0; n < 4; n++){
                    nextr = row + direction[n];
                    nextc = col + direction[n+1];
                    if(nextr < 0 || nextr >= grid.size() || nextc < 0 || nextc >= grid[0].size())
                        continue;
					// 先导入再填海会导致出现两个的岛格可能会导入相同的海格,比如:[-1, 0, -1] 这会导致大量重复海格进入队列
                    if(grid[nextr][nextc] == 0)
                        q.push(make_pair(nextr, nextc));
                    else if(grid[nextr][nextc] == 1)
                        return min;
                }
            }
        }
        return 0;
    }
    void DFS(vector<vector<int>>& grid, queue<pair<int, int>>& q, int row, int col){
        if(row < 0 || row >= grid.size() || col < 0 || col >= grid[0].size())
            return;
        if(grid[row][col] == 1){
            grid[row][col] = -1;
            DFS(grid, q, row+1, col);
            DFS(grid, q, row-1, col);
            DFS(grid, q, row, col+1);
            DFS(grid, q, row, col-1);
        }else if(grid[row][col] == 0) q.push(make_pair(row, col));  // 保存 -1 岛的一格沿海
    }
public:
    int shortestBridge(vector<vector<int>>& grid) {
        // 有且只有两座岛,返回必须翻转的 0 的最小数目,可以保证答案至少是 1
        // 分别标记两个岛,即一个岛为1,另二个岛为-1,海为0
        // 只需要遍历一个岛然后将其修改为-1,而另一个不需要遍历修改,则可以区分它们
        int row, col;
        queue<pair<int, int>> q;    // 保存 -1 岛的所有格子
        for(row = 0; row < grid.size(); row++){
            for(col = 0; col < grid[0].size(); col++){
                if(grid[row][col] == 1){
                    DFS(grid, q, row, col);
                    break;
                }
            }
            if(col < grid[0].size()) break;
        }
        // 从 -1 岛进行 BFS
        return BFS(grid, q);
    }
};

我自己的(改进——修改逻辑—— BFS 时先填海再查找导入):


class Solution {
    vector<int> direction{-1, 0, 1, 0, -1};
    int BFS(vector<vector<int>>& grid, queue<pair<int, int>>& q){
        int row, col, nextr, nextc, min = 0, times;
        while(!q.empty()){
            min++;  // 答案至少是 1
            times = q.size();
            while(times--){
                row = q.front().first;
                col = q.front().second;
                q.pop();
                for(int n = 0; n < 4; n++){
                    nextr = row + direction[n];
                    nextc = col + direction[n+1];
                    if(nextr < 0 || nextr >= grid.size() || nextc < 0 || nextc >= grid[0].size())
                        continue;
                    if(grid[nextr][nextc] == 0){
                        grid[nextr][nextc] = -1;    // 填海
                        q.push(make_pair(nextr, nextc));
                    }else if(grid[nextr][nextc] == 1)
                        return min;
                }
            }
        }
        return 0;
    }
    void DFS(vector<vector<int>>& grid, queue<pair<int, int>>& q, int row, int col){
        if(row < 0 || row >= grid.size() || col < 0 || col >= grid[0].size())
            return;
        if(grid[row][col] == 1){
            grid[row][col] = -1;
            DFS(grid, q, row+1, col);
            DFS(grid, q, row-1, col);
            DFS(grid, q, row, col+1);
            DFS(grid, q, row, col-1);
        }else if(grid[row][col] == 0){
            grid[row][col] = -1;    // 填海
            q.push(make_pair(row, col));  // 保存 -1 岛的一格沿海
        }
    }
public:
    int shortestBridge(vector<vector<int>>& grid) {
        // 有且只有两座岛,返回必须翻转的 0 的最小数目,可以保证答案至少是 1
        // 分别标记两个岛,即一个岛为1,另二个岛为-1,海为0
        // 只需要遍历一个岛然后将其修改为-1,而另一个不需要遍历修改,则可以区分它们
        int row, col;
        queue<pair<int, int>> q;    // 保存 -1 岛的所有格子
        for(row = 0; row < grid.size(); row++){
            for(col = 0; col < grid[0].size(); col++){
                if(grid[row][col] == 1){
                    DFS(grid, q, row, col);
                    break;
                }
            }
            if(col < grid[0].size()) break;
        }
        // 从 -1 岛进行 BFS
        return BFS(grid, q);
    }
};
复杂度分析
  • 时间复杂度:O(MN)O(MN)O(MN),其中 MMM 和 NNN 分别是数组 gridgridgrid 的行数和列数。
  • 空间复杂度:O(MN)O(MN)O(MN)。
PCB工艺-SI9000使用教程 本文介绍了阻抗计算工具SI9000的使用方法,重点讲解了微带线与带状线的区别、共面阻抗概念及参考面选择。通过USB差分走线实例,详细说明了如何选择计算模型、填写参数并确定线宽线距。文章还提供了层叠设计资料和工厂常规阻抗表格作为参考,建议制板时标注需控阻抗的线路供板厂调整。最后简单提及了嘉立创阻抗计算工具作为备选方案。 阅读详情

相关推荐

Python经常遇到导入xlwings就出错,如何解决

Python经常在导入xlwings时遇到错误。有人建议尝试重装或升级xlwings,但这些操作后仍然无法解决导入错误问题。

felix_8的博客 1739

【LeetCode】第934题——最短的桥(难度:中等)

【LeetCode】第934题——最短的桥(难度:中等)题目描述解题思路代码详解注意点 题目描述 在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。) 现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。 返回必须翻转的 0 的最小数目。(可以保证答案至少是 1 。) 示例 1: 输入:A = [[0,1],[1,0]] 输出:1 示例 2: 输入:A = [[0,1,0],[0,0,0],[0,0,1]] 输出:2 示例 3: 输入:A = [[

Se7en_Dayz的博客 656

一、两电平IGBT整流器

电压源换流器(Voltage source converter,VSC)连接交流主网和直流电网,起到交直流网络连接、功率输送和电能变换的作用。采用电压控制手段可维持直流电压的稳定;或采用功率控制手段保证系统功率输出达到预期。VSC的三相电压平衡方程如式(1)所示:式中,igx和ugx分别表示主网三相电流与电压(x=a,b,c);ucx表示换流器VSC 交流输出电压;Rg表示交流主网等效电阻;Lg表示交流主网等效电感。

TUCHACHINA的博客 4156

最短的桥(java)

岛 是由四面相连的 1 形成的一个最大组,即不会与非组内的任何其他 1 相连。grid 中 恰好存在两座岛。给你一个大小为 n x n 的二元矩阵 grid ,其中 1 表示陆地,0 表示水域。你可以将任意数量的 0 变为 1 ,以使两座岛连接起来,变成 一座岛。返回必须翻转的 0 的最小数目。

lianggege88的博客 300

泰克示波器TDS210改装便携示波器

泰克示波器TDS210改装编写示波器

超级网吧的博客 3079

Python 爬虫进阶技巧:定时爬虫任务实现无人值守采集

常规爬虫多依赖手动触发脚本运行,单次采集完成后需人工二次启动,无法满足日常周期性数据监控、行情抓取、资讯同步、业务台账定时归档等常态化采集需求。搭建可自主调度、自动启停、周期循环的定时爬虫任务,脱离人工干预实现无人值守全自动采集,是爬虫从临时脚本走向工程化落地的关键一步。schedule 轻量定时库官方文档APScheduler 高级定时框架官方文档Python time 内置模块官方文档Linux crontab 定时任务官方手册。

2503_91057718的博客 1117

JAVA程序设计:最短的桥(LeetCode:934)

在给定的二维二进制数组A中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。) 现在,我们可以将0变为1,以使两座岛连接起来,变成一座岛。 返回必须翻转的0 的最小数目。(可以保证答案至少是 1。) 示例 1: 输入:[[0,1],[1,0]] 输出:1 示例 2: 输入:[[0,1,0],[0,0,0],[0,0,1]] 输出:2 示例 3: 输入:[[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]...

信仰.的博客 717

基于Python的虚拟货币社区情绪分析与市场价格预测爬虫实现

本文探讨了如何利用Python爬虫技术获取虚拟货币社区数据,并通过情感分析预测市场价格走势。我们将使用最新的异步爬虫框架、自然语言处理技术和机器学习模型,构建一个完整的社区情绪分析系统。本文提供了详细的代码实现和理论解释,适合作为毕业设计参考。关键词:Python爬虫、虚拟货币、情感分析、价格预测、异步爬虫、机器学习爬虫框架aiohttp和httpx用于异步HTTP请求HTML解析和parsel数据存储MongoDB和Pandas用于数据处理自然语言处理库和VADER情感分析工具机器学习和。

2201_76125261的博客 521

Java实现 LeetCode 934.最短的桥(DFS+BFS)

在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。) 现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。 返回必须翻转的 0 的最小数目。(可以保证答案至少是 1。) 示例 1: 输入:[[0,1],[1,0]] 输出:1 示例 2: 输入:[[0,1,0],[0,0,0],[0,0,1]] 输出:2 示例 3: 输入:[[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]] 输出:1 提示:

Cypresszky的博客 599

(6)APB总线协议 —— 逻辑梳理(0.1认知)

这篇大家就差不多看看就行

CAUC_learner的博客 2702

手把手教你双目测距理论及生成视差图,深度图,点云图像

Stereo Vision, 也叫双目立体视觉,它的研究可以帮助我们更好的理解人类的双眼是如何进行深度感知的。双目视觉在许多领域得到了应用,例如城市三维重建、3D模型构建(如kinect fusion)、视角合成、3D跟踪、机器人导航(自动驾驶)、人类运动捕捉(Microsoft Kinect)等等。双目测距也属于双目立体视觉的一个应用领域,双目测距的基本原理主要是三角测量原理,即通过视差来判定物体的远近。

qq_53545309的博客 2280

力扣(LeetCode)934. 最短的桥(C语言)

[墨染] DFS+BFS,超好懂的模拟遍历操作。

墨染 642

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

LeetCode934. 最短的桥

1.问题 在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。) 现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。 返回必须翻转的 0 的最小数目。(可以保证答案至少是 1。) 示例 1: 输入:[[0,1],[1,0]] 输出:1 提示: 1 <= A.length = A[0].length <= 100 A[i][j] == 0...

rosefun96的博客 532

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

力扣LeetCode 934. 最短的桥

最短的桥

snoke_的博客 620

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【力扣每日一题】934.最短的桥

确定第一个岛屿范围后,我们将第一个岛屿的边界不断向外扩张,并同样标记,一层一层扩张下去,直到扩张到第二个岛屿,那么扩张的层数即是最短桥的长度,这个不断扩张的过程刚好用到的是广度优先方法。算法思想的主要流程是:先找到第一个岛屿的范围,并把这个岛屿范围内的值全部标记(如标记-1),这个过程可以用到深度优先方法。岛 是由四面相连的 1 形成的一个最大组,即不会与非组内的任何其他 1 相连。给你一个大小为 n x n 的二元矩阵 grid ,其中 1 表示陆地,0 表示水域。返回必须翻转的 0 的最小数目。

qq_44495605的博客 390

【LeetCode】934. 最短的桥

【LeetCode】934. 最短的桥

passnight的博客 953

LeetCode每日一题934. 最短的桥

LeetCode每日一题934. 最短的桥

weixin_46566527的博客 395

LeetCode 934.最短的桥

LeetCode 934.最短的桥 在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。) 现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。 返回必须翻转的 0 的最小数目。(可以保证答案至少是 1 。) // 广度优先搜索 - 通过先入先出的队列实现 class Solution { public: vector<int> direction{-1,0,1,0,-1}; int shortestBridge(vector<

m0_56077202的博客 743

leetcode-934:最短的桥

题目连接在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。返回必须翻转的 0 的最小数目。(可以保证答案至少是 1 。)示例 1: 示例 2: 示例 3: 解题 方法一:BFS 1.首先遍历,找到其中岛屿的一个点 2.将第一步中找到的那个岛屿全部标记成-1 3.从第一个岛屿出发,开始BFS,一但遇到1,就说明遇到第二个岛屿了...

菊头蝙蝠的博客 327

leetcode:934. 最短的桥

代码】leetcode934.最短的桥。

OceanStar的博客 281

Leetcode 934:最短的桥

题目描述 在给定的二维二进制数组A中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。) 现在,我们可以将0变为1,以使两座岛连接起来,变成一座岛。 返回必须翻转的0 的最小数目。(可以保证答案至少是 1。) 示例 1: 输入:[[0,1],[1,0]] 输出:1 示例 2: 输入:[[0,1,0],[0,0,0],[0,0,1]] 输出:2 示例 3: 输入...

weixin_35338624的博客 553

[LeetCode] 934、最短的桥

题目描述 在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组)现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。返回必须翻转的 0 的最小数目。 输入:[[0,1,0],[0,0,0],[0,0,1]] 输出:2 解题思路 算是比较好的一个题,直接想法是搜索:首先找到这两座岛,随后选择一座,将它不断向外延伸一圈,直到到达了另一座岛。在寻找这两座岛时...

aift的专栏 555

day66—BFS—最短的桥(LeetCode-934)

day66—BFS—最短的桥(LeetCode-934)

the_dry的博客 317

LeetCode-934. 最短的桥

形成的一个最大组,即不会与非组内的任何其他。,以使两座岛连接起来,变成。

m0_75107602的博客 602

leetcode.934 最短的桥 - dfs+bfs综合应用

dfs+bfs

weixin_61639349的博客 288

Leetcode编程C++之934. 最短的桥

岛 是由四面相连的 1 形成的一个最大组,即不会与非组内的任何其他 1 相连。grid 中 恰好存在两座岛。给你一个大小为 n x n 的二元矩阵 grid ,其中 1 表示陆地,0 表示水域。你可以将任意数量的 0 变为 1 ,以使两座岛连接起来,变成 一座岛。返回必须翻转的 0 的最小数目。

Passbyer 320
上一篇: Leetcode(51)——N 皇后
下一篇: Leetcode(684)——冗余连接
486L
博客等级 码龄7年 20粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值