###### tags: `LeetCode` `Medium` `DFS` `BFS` `Queue` `Recursion` # LeetCode #934 [Shortest Bridge](https://leetcode.com/problems/shortest-bridge/) ### (Medium) 在給定的二維二進制數組 A 中,存在兩座島。 (島是由四面相連的 1 形成的一個最大組。) 現在,我們可以將 0 變為 1,以使兩座島連接起來,變成一座島。 返回必須翻轉的 0 的最小數目。 (可以保證答案至少是 1 。) --- 由於題目規定只有兩座島, 因此可以用 [#200](https://hackmd.io/v2SDr-XNTx2nJOJc7-kaNQ) 的方式找到其中一座島嶼, 並把它標為2, 然後用goto跳脫迴圈。 接下來將所有2的位置都放入Queue中, 然後進行BFS, 當探索到座標點的值為1時, 代表找到另一座島, 此時回傳步數-1(因為只要算兩島間距離)即可。 --- ``` class Solution { public: int shortestBridge(vector<vector<int>>& grid) { for(int i=0;i<grid.size();i++){ for(int j=0;j<grid[0].size();j++){ if(grid[i][j]==1){ dfs(grid, i, j); goto startpoint; } } } startpoint: vector<vector<int>> visited(grid.size(), vector<int>(grid[0].size(), 0)); queue<pair<int,int>> q;// i, j for(int i=0;i<grid.size();i++){ for(int j=0;j<grid[0].size();j++){ if(grid[i][j]==2){ q.push({i,j}); } } } int ans = 0; while(!q.empty()){ for(int i=q.size();i>0;i--){ auto p = q.front();q.pop(); int ii=p.first, jj = p.second; if(ii<0||jj<0||ii==grid.size()||jj==grid[0].size()||visited[ii][jj]==1)continue; if(grid[ii][jj]==1)return ans-1; visited[ii][jj]=1; q.push({ii-1,jj}); q.push({ii,jj+1}); q.push({ii+1,jj}); q.push({ii,jj-1}); } ans++; } return ans-1; } void dfs(vector<vector<int>>& grid, int i, int j){ if(i<0||j<0||i==grid.size()||j==grid[0].size()||grid[i][j]==0||grid[i][j]==2)return; grid[i][j]=2; dfs(grid, i-1, j); dfs(grid, i, j+1); dfs(grid, i+1, j); dfs(grid, i, j-1); } }; ```