【最短的桥】

最短的桥
在这里插入图片描述
题解思路:
明确两个岛不会相连,所求翻转0的最小数目,就是两个岛之间的最短距离,那么距离该怎么求,想到用广度优先,让某一岛的所有结点都向四个方向扩展一圈,视为step=1;如果在扩展中遇到了岛2,那么说明以及连接成了一座岛,立即return step;中断扩展。
扩展一圈完成才能step++

int shortestBridge(int** grid, int gridSize, int* gridColSize) {
    int n = gridSize;
    int dirs[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};//上下左右四个方向
    int *island = (int *)malloc(sizeof(int) * n * n); //第一座岛的位置集合
    int *queue = (int *)malloc(sizeof(int) * n * n);//岛1的扩展队列,广度优先搜索队列
    int head = 0, tail = 0;//队头,队尾
    //n x n矩阵
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (grid[i][j] == 1) {//遇到一个岛的一块
                queue[tail++] = i * n + j;//
                grid[i][j] = -1;//与另一岛做区别,在此对1岛都置-1
                int islandSize = 0;
                while (head != tail) {//队不空
                    int x = queue[head] / n;
                    int y = queue[head] % n;
                    island[islandSize++] = queue[head];
                    head++;
                    for (int k = 0; k < 4; k++) {//上下左右广度搜索
                        int nx = x + dirs[k][0];
                        int ny = y + dirs[k][1];
                        if (nx >= 0 && ny >= 0 && nx < n && ny < n && grid[nx][ny] == 1) {
                            queue[tail++] = nx * n + ny;
                            grid[nx][ny] = -1;
                        }
                    }
                }//执行到这一步就已经标记完成1岛的全部位置,全部置为-1,因为岛是相连的,找到一个1,再对其进行广度遍历,则会找到全部位置

                //下面就是对1岛进行扩展
                head = tail = 0;
                for (int i = 0; i < islandSize; i++) {
                    queue[tail++] = island[i];
                }
                int step = 0;
                while (head != tail) {
                    int sz = tail - head;
                    for (int i = 0; i < sz; i++) {//一次广度优先搜索完成,岛屿扩展一圈,下面step++
                        int x = queue[head] / n;
                        int y = queue[head] % n;
                        head++;
                        for (int k = 0; k < 4; k++) {
                            int nx = x + dirs[k][0];
                            int ny = y + dirs[k][1];//一位数组存储,恢复二维状态
                            if (nx >= 0 && ny >= 0 && nx < n && ny < n) {
                                if (grid[nx][ny] == 0) {//不超边界并且是水域,扩展该位置
                                    queue[tail++] = nx * n + ny;
                                    grid[nx][ny] = -1;
                                } else if (grid[nx][ny] == 1) {//偶遇2岛,立即结束,返回step
                                    free(queue);
                                    free(island);
                                    return step;
                                }
                            }
                        }
                    }
                    step++;
                }
            }
        }
    }
    return 0;
}
/*
肯定有两个岛屿
上下左右找一条最短的路将两个岛连起来
*/

总结:中等题目好难,与图有关的题好复杂,时间复杂度一般也高,代码量也多,真的太难了,理解原理还行,只不过自己想不出来,看过题解大概懂了,不过代码根本无从下手,对bfs理解不够深入,运用就更扯了,题解代码看了一小时,写了注释,基本看懂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值