题目简介:
给你一个大小为 n x n
的二元矩阵 grid
,其中 1
表示陆地,0
表示水域。
岛 是由四面相连的 1
形成的一个最大组,即不会与非组内的任何其他 1
相连。grid
中 恰好存在两座岛 。
你可以将任意数量的 0
变为 1
,以使两座岛连接起来,变成 一座岛 。
返回必须翻转的 0
的最小数目。
示例 1:
1 2
| 输入:grid = [[0,1],[1,0]] 输出:1
|
示例 2:
1 2
| 输入:grid = [[0,1,0],[0,0,0],[0,0,1]] 输出:2
|
示例 3:
1 2
| 输入:grid = [[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
|
提示:
n == grid.length == grid[i].length
2 <= n <= 100
grid[i][j]
为 0
或 1
grid
中恰有两个岛
思路:
首先找到第一个岛,通过深度优先搜索将第一个岛都标为-1。
然后通过广度优先搜索,从第二个岛出发,每次往外延伸一圈,每一次延伸说明总距离+1,当遇到任意的-1时,即两个岛相连。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| class Solution { public:
int dx[4] = {0, 1, 0, -1}; int dy[4] = {-1, 0, 1, 0};
void solve(vector<vector<int>>& grid, int x, int y){
if(grid[x][y] == 1) grid[x][y] = -1; else return;
for(int i = 0; i < 4; i++){
int now_x = x + dx[i]; int now_y = y + dy[i];
if(now_x >= 0 && now_x < grid.size() && now_y >= 0 && now_y < grid.size()){
solve(grid, now_x, now_y); } } }
int shortestBridge(vector<vector<int>>& grid) {
int flag = 0;
for(int i = 0; i < grid.size(); i++){
for(int j = 0; j < grid.size(); j++){
if(grid[i][j] == 1){
flag = 1; solve(grid, i, j); break; } }
if(flag == 1) break; }
queue<pair<int, int>> qu; for(int i = 0; i < grid.size(); i++){
for(int j = 0; j < grid.size(); j++){
if(grid[i][j] == 1){
qu.push(make_pair(i, j)); } } }
int res = -1; while(!qu.empty()){
res++; int size = qu.size();
for(int i = 0; i < size; i++){ int x = qu.front().first; int y = qu.front().second; for(int j = 0; j < 4; j++){
int now_x = x + dx[j]; int now_y = y + dy[j];
if(now_x >= 0 && now_x < grid.size() && now_y >= 0 && now_y < grid.size()){
if(grid[now_x][now_y] == 0){
grid[now_x][now_y] = 1; qu.push(make_pair(now_x, now_y)); } else if(grid[now_x][now_y] == -1){
return res; } } }
qu.pop(); } }
return res;
} };
|