LC 1254:統計封閉島嶼的數目(DFS)

統計封閉島嶼的數目


問題描述:
有一個二維矩陣 grid ,每個位置要麼是陸地(記號爲 0 )要麼是水域(記號爲 1 )。

我們從一塊陸地出發,每次可以往上下左右 4 個方向相鄰區域走,能走到的所有陸地區域,我們將其稱爲一座「島嶼」。

如果一座島嶼完全由水域包圍,即陸地邊緣上下左右所有相鄰區域都是水域,那麼我們將其稱爲 「封閉島嶼」。

請返回封閉島嶼的數目。

示例1:

輸入:grid = [[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],[1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]]
輸出:2
解釋:
灰色區域的島嶼是封閉島嶼,因爲這座島嶼完全被水域包圍(即被 1 區域包圍)。

示例2:

輸入:grid = [[1,1,1,1,1,1,1],
[1,0,0,0,0,0,1],
[1,0,1,1,1,0,1],
[1,0,1,0,1,0,1],
[1,0,1,1,1,0,1],
[1,0,0,0,0,0,1],
[1,1,1,1,1,1,1]]
輸出:2

解題思路:

  首先我們需要遍歷整個島嶼,如果當前位置爲0(陸地),我們就需要判斷該位置所在的島嶼是否爲封閉島嶼。dfs上下左右四個方向,如果四個方向全部都是陸地,則返回真,總數+1。(注意:dfs的時候需要把碰到陸地標記爲水域,這樣就可以避免下一次遍歷的時候重複計算了)
  此題不需要回溯,因爲是求同一區域,不需要計算路徑。

圖解:

第一次從左上角開始進入dfs

(1)變爲1,並從四個方向dfs

(2)第一次返回0,並把陸地0都變成了水域1.

(3)當進入四周都是水域的陸地時,返回1

代碼如下:

#include<iostream>
#include<vector>
using namespace std;
	int dfs(int i,int j,vector<vector<int> >& grid){
		if(i<0||j<0||i>=grid.size()||j>=grid[i].size()){//不滿足條件 
			return 0;
		}
		if(grid[i][j]==1){//如果碰到水域返回1 
			return 1;
		}
		grid[i][j]=1;//如果碰到陸地則標記爲水域 
		int x1= dfs(i+1,j,grid);
		int x2= dfs(i-1,j,grid);
		int y1= dfs(i,j+1,grid);
		int y2= dfs(i,j-1,grid);
		//四個方向全爲水域返回1 
		if(x1&&x2&&y1&&y2){
			return 1;
		}
		return 0;
	}
	int closedIsland(vector<vector<int> >& grid) {
		int sum=0;
		for(int i=1;i<grid.size()-1;i++){//邊緣部分肯定不是島嶼,所以從1開始 
			for(int j=1;j<grid[i].size()-1;j++){
				if(grid[i][j]==0){ //如果是陸地 
					if(dfs(i,j,grid)){
						sum++;
						}
					}
				}
		} 
			return sum;
    }
    
int main(){
	vector<vector<int> > grid={{0,0,1,1,0,1,0,0,1,0},{1,1,0,1,1,0,1,1,1,0},{1,0,1,1,1,0,0,1,1,0},{0,1,1,0,0,0,0,1,0,1},{0,0,0,0,0,0,1,1,1,0},{0,1,0,1,0,1,0,1,1,1},{1,0,1,0,1,1,0,0,0,1},{1,1,1,1,1,1,0,0,0,0},{1,1,1,0,0,1,0,1,0,1},{1,1,1,0,1,1,0,1,1,0}};
	cout<<closedIsland(grid);
	return 0;
}
	

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章