從LeetCode學演算法 - 45 DFS (1)
0200 Number of Islands (Medium)
寫在前面: 如果覺得這篇有幫助到您的話, 請幫我隨手點開最下面的SHOW EMBED並拍5下手~ (當然,Medium的拍手也可以多拍幾下啦XD) 這樣我再寫個十多篇以後應該就有買一杯咖啡的$$了XDDDDD (聽起來超少哈哈)
Question:
Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
Example 1:
Input:
11110
11010
11000
00000Output: 1Example 2:
Input:
11000
11000
00100
00011Output: 3分析/解題: 給定一個二維的地圖當中陸地用'1'表示,水則用'0'表示, 試計數這整張圖有多少島嶼(island)。可假定地圖的外圍均為水域。 (島嶼的定義就是其周圍都圍繞著水, 且可以通過連接相鄰的垂直/水平陸地所構成。)
如對於題目描述依舊沒搞懂的話,就把它當成小畫家填色的色塊吧! 視為相同區域的用油漆桶可以全部填滿XD 而題目所問的,就相當於要填幾次才能將所有陸地區域填滿。
對於要確認島嶼這點,只有一種方法: 每次從一個點開始向外延伸相鄰的格子, 直到周圍沒有可以延伸的區域為止。 這時候這整塊區域就是我們所謂的島嶼,於是計數可以加1。 那麼問題來了,在延伸的過程中一共有四個方向可以選擇, 如果不加限制的話,無疑會有重複的部分; 所以除了檢查是否遇到水(‘0’,也就是可以不用繼續往下搜尋)外, 我們還需要知道這個格子是否已經走過了。 所以我們會再新增一個visited陣列用來標明已經走過的區域。 (這樣子只要已經走過的就直接跳過即可。)
由於每次會需要走到底才會回頭, 所以這種方式是很典型的DFS(Depth-First Search,深度優先搜尋)方法。
所以流程會變成: 1. 初始化一個visited二維陣列,預設當中每個值均為false 2. 對grid中的每個點(i, j)檢查其是否為陸地(‘1’),且未曾走訪過的話: 2-a. 遞增島嶼計數值,並從每個點(i, j)呼叫函式dfs來開始走訪 3. 在dfs中,先檢查(i, j)點是否符合規範(因會+1或-1,須不超出範圍), 且尚未走訪過(visited[i][j] == false)的狀況,進行3-a的流程 3-a. 將visited[i][j]設定為true 3-b. 往(i, j)的上下左右走,並傳入下一階段的dfs。
這麼一來,當整張圖掃過去以後, 我們就能知道到底有幾個島嶼了!
Java和Python的寫法基本一致,這邊不再贅述, 讀者只要注意到應該被檢查的邊界條件即可。
Java:





