934. Shortest Bridge

问题:

给定n*n二维数组,

1代表陆地,0代表海洋。

上下左右为相连,那么相连的 1 构成岛屿,

那么给定的数组共构成两个岛屿,

求填海,最少填多少个cell能够将两个岛屿相连。

Example 1:
Input: A = [[0,1],[1,0]]
Output: 1

Example 2:
Input: A = [[0,1,0],[0,0,0],[0,0,1]]
Output: 2

Example 3:
Input: 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]]
Output: 1
 
Constraints:
2 <= A.length == A[0].length <= 100
A[i][j] == 0 or A[i][j] == 1

  

解法:BFS

两次BFS:

  • 找寻第一个岛屿 2(所有坐标)。
  • 从第一个岛屿2扩展寻找,试图连接另一个岛屿 1。

首先使用BFS,

遍历到为 1 的cell,进行扩展(利用queue,cell==1扩展),标记当前遇到的岛屿为 2,将岛屿cell由 1 更新为 2。

同时将该岛屿的所有坐标加入 另一个队列中(用于寻找填海cell),且标记visited。

 

在上述的岛屿 2 的构建中,我们获得了岛屿 2 的cell集合。

将这些cell入队后,再进行BFS,遇到!=2的cell,(0:海洋 or 1:另一个岛屿)进行扩展,

同时记录展开层数step。

直到遇到 cell==1 ,证明连上另一个岛屿。

返回 step。

 

代码参考:

 1 class Solution {
 2 public:
 3     int n=0;
 4     int dir[5] = {1,0,-1,0,1};
 5     /*void printvector(vector<vector<int>>& A) {
 6         cout<<"{";
 7         for(int i=0; i<n; i++) {
 8             cout<<"{";
 9             for(int a:A[i]) cout<<a<<",";
10             cout<<"}"<<endl;
11         }
12         cout<<"}"<<endl;
13     }*/
14     void color(vector<vector<int>>& A, int i, int j,
15                queue<int>& q_all, unordered_set<int>& visit_all) {
16         queue<int> q;
17         unordered_set<int> visited;
18         q.push(i*100+j);
19         visited.insert(i*100+j);
20         while(!q.empty()) {
21             int sz = q.size();
22             for(int k=0; k<sz; k++) {
23                 int cur = q.front();
24                 q.pop();
25                 q_all.push(cur);
26                 visit_all.insert(cur);
27                 A[cur/100][cur%100]=2;
28                 for(int d=1; d<5; d++) {
29                     int x = cur/100+dir[d-1];
30                     int y = cur%100+dir[d];
31                     if(x<0 || y<0 || x>=n || y>=n || A[x][y]!=1) continue;
32                     if(visited.insert(x*100+y).second) {
33                         q.push(x*100+y);
34                     }
35                 }
36             }
37         }
38     }
39     int shortestBridge(vector<vector<int>>& A) {
40         n = A.size();
41         queue<int> q;
42         unordered_set<int> visited;
43         for(int i=0; i<n; i++) {
44             for(int j=0; j<n; j++) {
45                 if(A[i][j]==1) {
46                     color(A, i, j, q, visited);
47                     break;
48                 }
49             }
50             if(visited.size()>0) break;
51         }
52         //printvector(A);
53         int step=-1;
54         while(!q.empty()) {
55             int sz=q.size();
56             for(int i=0; i<sz; i++) {
57                 int cur = q.front();
58                 q.pop();
59                 //cout<<"q.pop:"<<cur/100<<","<<cur%100<<"A(x,y):"<<A[cur/100][cur%100]<<endl;
60                 if(A[cur/100][cur%100]==1) return step;
61                 for(int d=1; d<5; d++) {
62                     int x = cur/100+dir[d-1];
63                     int y = cur%100+dir[d];
64                     if(x<0 || y<0 || x>=n || y>=n) continue;
65                     if(visited.insert(x*100+y).second) {
66                         q.push(x*100+y);
67                     }
68                 }
69             }
70             step++;
71         }
72         return -1;
73     }
74 };

 

posted @ 2021-03-13 13:36  habibah_chang  阅读(59)  评论(0编辑  收藏  举报