題目:給定一個由 ‘1’(陸地)和 ‘0’(水)組成的的二維網格,計算島嶼的數量。一個島被水包圍,並且它是通過水平方向或垂直方向上相鄰的陸地連接而成的。你可以假設網格的四個邊均被水包圍。
示例 1:
輸入:
11110
11010
11000
00000
輸出: 1
示例 2:
輸入:
11000
11000
00100
00011
輸出: 3
本題可以用深度優先搜索(DFS)來解決,深度優先搜索也稱爲回溯(back tracking)。
不同於BFS,DFS要用到遞歸。
DFS的一般思路:
在搜索過程中訪問某個頂點後,需要遞歸地訪問此頂點的所有未訪問過的相鄰頂點。
初始條件下所有節點爲白色,選擇一個作爲起始頂點,按照如下步驟遍歷:
a. 選擇起始頂點塗成灰色,表示還未訪問 ;
b. 從該頂點的鄰接頂點中選擇一個,繼續這個過程(即再尋找鄰接結點的鄰接結點),一直深入下去,直到一個頂點沒有鄰接結點了,塗黑它,表示訪問過了 ;
c. 回溯到這個塗黑頂點的上一層頂點,再找這個上一層頂點的其餘鄰接結點,繼續如上操作,如果所有鄰接結點往下都訪問過了,就把自己塗黑,再回溯到更上一層。
d. 上一層繼續做如上操作,知道所有頂點都訪問過。
本題思路與上述思路大體相似,題目中結點由‘1’和‘0’構成,‘1’爲有用的結點,找到一個‘1’,修改爲‘2’(也就是做一個標記,表示這個‘1’已經訪問過了),從該頂點的爲‘1’的鄰接頂點中選擇一個,同樣修改爲‘2’,繼續這個過程(即再尋找鄰接結點的爲‘1’的鄰接結點),一直深入下去,直到一個頂點沒有爲‘1’的鄰接結點了(即爲‘2’或者爲‘0’),返回,島嶼計數加一。直到訪問了所有的‘1’。
具體python代碼實現如下:
class Solution(object):
def dfs(self, grid, x, y, height, width):
if x<0 or x>=height:
return
if y<0 or y>=width:
return
if grid[x][y]=='2' or grid[x][y]=='0':
return
grid[x][y]='2'
self.dfs(grid, x-1, y, height, width)
self.dfs(grid, x+1, y, height, width)
self.dfs(grid, x, y-1, height, width)
self.dfs(grid, x, y+1, height, width)
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
if len(grid)==0:
return 0
else:
landsum = 0
height = len(grid)
width = len(grid[0])
for i in range(height):
for j in range(width):
if grid[i][j]=='1':
landsum+=1
self.dfs(grid,i,j,height,width)
return landsum