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

一、环境说明

  1. 本文是 LeetCode 934. 最短的桥,使用c语言实现。
  2. 模拟深度优先遍历+广度优先遍历。
  3. 测试环境:Visual Studio 2019。

二、代码展示

int dx[4]={-1,1,0,0};
int dy[4]={0,0,1,-1};
void dfs(int **grid,int n ,int x,int y, int *queue,int *tail){//传入矩阵,行数n,坐标x,y,队列queue,队尾大小tail
    //遍历过的点置-1,入队
    if(x<0||y<0||x>=n||y>=n||grid[x][y]!=1){
        return;//越界,或者不是陆地。
    }
    queue[(*tail)++] = x*n + y;//特殊编码,存储x/y
    grid[x][y] = -1;
    for(int i =0;i<4;i++){
        dfs(grid,n,x+dx[i],y+dy[i],queue,tail);//向四个方向遍历
    } 
}
int shortestBridge(int** grid, int gridSize, int* gridColSize){
    //n=gridSize=*gridColSize;
    int n= gridSize;//行数
    int i = 0,j = 0;
    for(i = 0;i<gridSize;i++){//找到第一块陆地
        for(j = 0;j<*gridColSize;j++){
            if(1==grid[i][j]){//遇到陆地
                goto haha;//当然能用goto都可以不用goto//删了goto的判断,把下面8行解除注释,效果一样。
            }
            // if(1==grid[i][j]){//遇到陆地
            //     break;
            // }
        }
        // if(j!=n)
        //     if(1==grid[i][j]){//遇到陆地
        //         break;
        //     }
    }
haha:;//程序员前辈在上,在下用goto了,为了节约时间,陷入魔道。
    int *queue = (int*)calloc(sizeof(int),n*n);//最多全部元素入栈
    int head = 0,tail = 0;//设置队列和队头队尾指针。
    dfs(grid,gridSize,i,j,queue,&tail);//递归遍历i、j,整座岛屿入队。
    int step = 0;//宽搜层数
    while(tail>head){
        int sz = tail - head;//队列元素个数
        for(int s = 0;s<sz;s++){//所有陆地和当前遍历到的水面
            int x = queue[head]/n;//行号
            int y = queue[head++]%n;//列号//head指向下一个位置
            for(int t = 0 ;t<4;t++){//整体向外扩展一步
                int new_x = x+dx[t];
                int new_y = y+dy[t];
                if(new_x>=0&&new_y>=0&&new_x<n&&new_y<n){//边界判断
                    if(0==grid[new_x][new_y]){//遇到水面
                        queue[tail++] = new_x *n +new_y;//水面入队
                        grid[new_x][new_y] = -1;//说明遍历过
                    }else if(1==grid[new_x][new_y]){//遍历到新大陆
                        free(queue);//释放队列
                        return step;//返回深搜层数
                    }
                }
            }
        }
        step++;//整座岛+遍历过的水域,向外延伸了一层
    }
    return 0;
}

三、思路分析

  • 题目给定 n × n n\times n n×n矩阵,保证有两座岛,求最短的桥。
  • 考虑遍历整个矩阵。找到陆地,则对陆地 D F S DFS DFS,得到整个岛的所有陆地。遍历到的陆地,我们将它置为 − 1 -1 1,这样就不会再次遍历。为了保存深搜结果,我们建立 q u e u e queue queue队列,将陆地入队。
  • q u e u e queue queue存储了一座岛的所有陆地。我们将这座岛,整体扩张,每次只向上下左右扩张一格。每次扩张后,可以想象,可能遇到:
  1. 自己的陆地 2. 水面 3. 新大陆
  • 自己的陆地,已经置 − 1 -1 1,跳过对它的遍历。
  • 水面,说明我们还没遇到新大陆。下次需要从水面继续扩张,所以水面入队 q u e u e queue queue,同时将它置 − 1 -1 1,不会再次遍历。
  • 新大陆,我们搜索的结果。到这里停止遍历,返回目前搜索的层数即可。

得到整座岛的陆地的操作,就是DFS深度优先遍历。
对岛屿扩张的操作,就是BFS宽度优先遍历。

四、博主致语

理解思路很重要!
欢迎读者在评论区留言,作为日更博主,看到就会回复的。

五、AC

AC

六、复杂度分析

  1. 时间复杂度: O ( n 2 ) O(n^2) O(n2) , n n n g r i d S i z e gridSize gridSize行数,一次遍历 g r i d grid grid矩阵的时间复杂度是 O ( n 2 ) O(n^2) O(n2)。二重循环只负责找到第一个陆地,找到就跳出循环了。总的来说,遍历找第一个陆地+第一个陆地DFS找整个岛+从第一个岛BFS得到最短的桥,总时间复杂度不会超过 O ( n 2 ) O(n^2) O(n2)
  2. 空间复杂度: O ( n 2 ) O(n^2) O(n2),当前需要遍历的 q u e u e queue queue队列的空间复杂度 O ( n 2 ) O(n^2) O(n2),最坏情况下, q u e u e queue queue内元素个数可能接近 n 2 n^2 n2
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清墨韵染

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值