问题:
给定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 };