
吐司寫LeetCode :1905. Count Sub Islands

topic: dfs
bfs
matrix
題目原文
題目連結: 點我
You are given two m x n
binary matrices grid1
and grid2
containing only 0
‘s (representing water) and 1
‘s (representing land). An island is a group of 1
‘s connected 4-directionally (horizontal or vertical). Any cells outside of the grid are considered water cells.
An island in grid2
is considered a sub-island if there is an island in grid1
that contains all the cells that make up this island in grid2
.
Return the number of islands in grid2
that are considered sub-islands.
Example 1:
Input:
grid1 = [[1, 1, 1, 0, 0], [0, 1, 1, 1, 1], [0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 1, 0, 1, 1]],
grid2 = [[1, 1, 1, 0, 0], [0, 0, 1, 1, 1], [0, 1, 0, 0, 0], [1, 0, 1, 1, 0], [0, 1, 0, 1, 0]]
Output:
3
Explanation:
In the picture above, the grid on the left is grid1 and the grid on the right is grid2.
The 1s colored red in grid2 are those considered to be part of a sub-island. There are three sub-islands.
Example 2:
Input:
grid1 = [[1,0,1,0,1],[1,1,1,1,1],[0,0,0,0,0],[1,1,1,1,1],[1,0,1,0,1]],
grid2 = [[0,0,0,0,0],[1,1,1,1,1],[0,1,0,1,0],[0,1,0,1,0],[1,0,0,0,1]]
Output:
2
Explanation:
In the picture above, the grid on the left is grid1 and the grid on the right is grid2.
The 1s colored red in grid2 are those considered to be part of a sub-island. There are two sub-islands.
Constraints:
m == grid1.length == grid2.length
n == grid1[i].length == grid2[i].length
1 <= m, n <= 500
grid1[i][j]
andgrid2[i][j]
are either0
or1
.
題解
題目中給我們兩張一樣大的地圖分別為 grid1
與 grid2
,兩張地圖由 0
和 1
組成,分別代表海洋與陸地,因此可從兩張地圖中看出島嶼的位置。
若在 grid2
上的某座島嶼對應到 grid1
上時,整座島嶼都位於 grid1
中的一座島嶼上,則可稱位於grid2
的該島嶼為子島嶼(Sub-island) 。本題想要我們找出在 grid2
上的所有子島嶼。
想一想
本題的邊長上限不大(最大地圖為500*500
),基本上可以用基本的 深度優先搜尋(Depth First Search,DFS) 與 廣度優先搜尋(Breadth First Search,BFS) 來做處理。
方法1: DFS
描述
dfs相信大家都很熟悉了把XD
深度優先搜尋(Depth First Search,DFS) 簡單來說就是透過一連串的遞迴(recursion)來對樹(tree)、圖(graph)等資料結構進行搜尋。這種演算法會盡可能的往樹或圖的深處走,因此稱為深度優先搜尋。
上圖範例的走訪順序為: A->B->C->D->E->F
上方的走訪方式是二元樹走訪中的先序遍歷(Preorder Traversal) ,之後有時間會再寫一篇文來介紹二元樹走訪。
以本題為例,我們會遍歷一次所有格子。在遍歷的途中,我們會對每個符合子島嶼條件的點做DFS,遍歷完後便可得到子島嶼總數。
每次DFS中,我們會針對每個點做以下三件事:
- 對該點做邊界檢測:若超出地圖邊界,回傳
0
- 偵測該點是否為海:若為海,回傳
0
- 偵測該點是否為違反子島嶼規則的陸地:若違反規則,則回傳
-1
- 對上、下、左、右四個相鄰點做DFS
- 將該點的值改為
0
,避免重複走訪
必須要整座島嶼的陸地皆符合子島嶼規則,該島嶼才能稱作是子島嶼
Code:
1 | // Author: Toast1001 |
時間複雜度(Time Complexity):O(n*m)
空間複雜度(Time Complexity):O(n*m)
結果
由於在做 DFS 的時候都有把走訪過的點紀錄,使所有點最多只會走訪一次,本質上就是在遍歷二維陣列,因此效率較高。
方法2: BFS
描述
bfs相信大家也很熟悉了把XD
廣度優先搜尋(Breadth First Search,BFS) 與 DFS 一樣,可用於樹與圖的遍歷。不一樣的是,BFS 會將同一深度的點都走訪完成後,再往下一層前進。這種演算法傾向系統地展開並檢查圖中的所有節點,故稱為廣度優先搜尋。
上圖範例的走訪順序為: A->B->E->C->D->F
遍歷時的邏輯大致與 DFS 一樣,在遍歷的途中,我們會對每個符合子島嶼條件的點做DFS,遍歷完後便可得到子島嶼總數。
Code:
1 | // Author: Toast1001 |
時間複雜度(Time Complexity):O(n*m)
空間複雜度(Time Complexity):O(n*m)
結果
本題使用 DFS 與 BFS 效率差不多,跑出來的成果都不錯。
小結
這種 DFS 與 BFS 問題常常在面試白板題與競賽中出現,如果學會的話,會對未來很有幫助哦~
那就老樣子啦,吐司寫 LeetCode,我們下次見,bye~ bye~
類題
LeetCode:
200. Number of Islands
1992. Find All Groups of Farmland