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

934.最短的桥

题目描述

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

示例图片

在这里插入图片描述

解题思路

方法深度优先+广度优先结合
算法思想的主要流程是:先找到第一个岛屿的范围,并把这个岛屿范围内的值全部标记(如标记-1),这个过程可以用到深度优先方法。
确定第一个岛屿范围后,我们将第一个岛屿的边界不断向外扩张,并同样标记,一层一层扩张下去,直到扩张到第二个岛屿,那么扩张的层数即是最短桥的长度,这个不断扩张的过程刚好用到的是广度优先方法。

为了更好的理解算法,这里借用LeetCode博主 “爪哇缪斯”的算法图解过程:
来自爪哇缪斯

代码

/** DFS寻找第一个岛屿元素 */
void DFS(int** grid,int gridSize,int i,int j,int *Queue,int *rear){
    if(i<0 || i>=gridSize || j<0 || j>=gridSize || grid[i][j]!=1){
        return;
    }
    /* 标记元素并入队 */
    Queue[(*rear)++]=i*gridSize+j;
    grid[i][j]=-1;
    /* 上下左右分别寻找 */
    DFS(grid,gridSize,i-1,j,Queue,rear);
    DFS(grid,gridSize,i+1,j,Queue,rear);
    DFS(grid,gridSize,i,j-1,Queue,rear);
    DFS(grid,gridSize,i,j+1,Queue,rear);
    return;
}

int shortestBridge(int** grid, int gridSize, int* gridColSize){
    //创建队列并初始化
    int *Queue=(int *)malloc(sizeof(int)*gridSize*gridSize);
    int front,rear; front=rear=0;
    int xy[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
    int i,j,x,y,xx,yy,step;
    int flag=0; //标记元素
    int num; //岛屿元素个数

    /* DFS寻找第一个岛 */
    for(i=0;i<gridSize;i++){
        for(j=0;j<gridSize;j++){
            if(grid[i][j]==1){
                DFS(grid,gridSize,i,j,Queue,&rear);
                flag=1; break;
            }
        }
        if(flag==1){ break; }
    }
    step=0;
    /* BFS 第一个岛屿向外扩散 */
    while(front!=rear){
        num=rear-front;
        for(i=1;i<=num;i++){
            //队列第一个元素出队
            x = Queue[front] / gridSize;
            y = Queue[front] % gridSize;
            front++;
            for(j=0;j<4;j++){ //判断上下左右是否有0,有0扩散
                xx=x+xy[j][0];
                yy=y+xy[j][1];
                if (xx < 0 || xx >= gridSize || yy < 0 || yy >= gridSize || grid[xx][yy] == -1) {
                    continue;
                }
                if(grid[xx][yy]==1){
                    return step;
                }
                /* 扩散元素标记入队 */
                grid[xx][yy]=-1;
                Queue[rear++]=gridSize*xx+yy;
            }
        }
        step++;
    }
    free(Queue);
    return step;
}

提交结果

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值