iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
自我挑戰組

30天 LeetCode 演算法實戰:Java 與 Python 解法比較系列 第 22

Day 22|Number of Islands:Java 與 Python 實作 DFS / BFS

  • 分享至 

  • xImage
  •  

一、題目介紹
今天要練習的題目是LeetCode 200:Number of Islands

題目會給我們一個由10組成的二維grid

  • 1代表陸地
  • 0代表水
    如果多個1透過上下左右相鄰,就屬於同一座島嶼
    我們需要計算整個grid中總共有幾座島嶼

例如:
grid =
[
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
這個例子中所有相連的1都屬於同一座島,所以答案是:1

另一個例子:
grid =
[
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
可以找到三個互相沒有連接的區域,因此答案是:3

二、解題思路
這題可以使用DFS(深度優先搜尋)BFS(廣度優先搜尋)

我們可以從左上角開始逐格檢查
如果遇到0
→ 跳過

如果遇到1
→ 找到一座新的島嶼
→ islandCount + 1
→ 將這座島嶼所有相連的陸地找出來

這裡最重要的一點是:同一座島只能計算一次

例如:
1 1
1 1
雖然有四個1,但它們全部相連,所以只能算1座島
因此找到一個1後,就要把與它連通的所有1都標記成「已經搜尋過」

三、使用DFS搜尋島嶼
假設我們在這個位置找到1
0 0 0
0 1 0
0 0 0

就從這個位置開始往四個方向搜尋
https://ithelp.ithome.com.tw/upload/images/20260910/20178669a801I0h9S6.png

只要遇到相鄰的1,就繼續DFS
為了避免重複搜尋,可以把拜訪過的1改成0

例如:
1 1 0
1 1 0
0 0 0

搜尋完成後變成
0 0 0
0 0 0
0 0 0

這樣之後掃描到這些位置時,就不會再次計算同一座島嶼

四、Java實作DFS
https://ithelp.ithome.com.tw/upload/images/20260910/20178669fFrDlVSgSH.png

https://ithelp.ithome.com.tw/upload/images/20260910/20178669KMKjspPc2r.png

五、Python實作DFS
https://ithelp.ithome.com.tw/upload/images/20260910/20178669BECFTEliAY.png

https://ithelp.ithome.com.tw/upload/images/20260910/20178669EQyWkNgF6b.png

七、BFS解法
除了DFS,也可以使用BFS

DFS使用遞迴一路深入
起點

往下一個陸地

繼續搜尋

直到不能走

BFS則是利用Queue
起點

第一層相鄰陸地

第二層相鄰陸地

繼續向外擴散

Java BFS
https://ithelp.ithome.com.tw/upload/images/20260910/201786696QizUC211B.png
https://ithelp.ithome.com.tw/upload/images/20260910/20178669sGOqsjTfe6.png

https://ithelp.ithome.com.tw/upload/images/20260910/20178669XIeZdwIn5k.png

八、Java與Python解法比較
https://ithelp.ithome.com.tw/upload/images/20260910/20178669PpwhoX6VXk.png

九、時間與空間複雜度
假設grid的大小為m × n

時間複雜度:O(m × n)

  • 外層雙層迴圈會掃描整個Grid,而每個陸地最多只會被DFS / BFS處理一次

空間複雜度:O(m × n)

  • DFS的遞迴呼叫在最壞情況下可能包含大量連續的陸地

十、Day 21 Flood Fill 與 Day 22 Number of Islands 比較
https://ithelp.ithome.com.tw/upload/images/20260910/201786698mA9gFpk8b.png

兩題最大的共同點就是:Grid上的連通區域搜尋。
Day 21 是「找到一個區域並修改它」,Day 22 則是「找到一個區域並計數」

十一、實作結果
Leetcode測試結果:Accepted

十二、今日學習心得
今天的Number of Islands延續了昨天Flood Fill的概念,讓我更加理解DFS與BFS在二維Grid中的應用方式。這題最重要的地方,是找到一個1時不能只把它當成一個陸地計算,而是要繼續搜尋與它上下左右相連的所有陸地,將整個連通區域視為同一座島。

在實作過程中,我也了解到「標記已拜訪的位置」是Grid搜尋中非常重要的技巧。這次直接將1 修改成0,就可以避免同一座島被重複計算,也不需要額外建立visited陣列。

和 Day 21 的 Flood Fill 比較後,我發現兩題雖然題目看起來不同,但背後使用的搜尋概念非常接近。Flood Fill 是找到連通區域後修改顏色,而 Number of Islands 是找到連通區域後進行計數。這讓我開始了解到,學習演算法時不一定要只記住單一題目的解法,更重要的是找出不同問題背後共通的解題模式。

今天也再次練習了 DFS 與 BFS,讓我對 Grid、連通區域以及四方向搜尋有更完整的理解。這些概念未來也可以應用在迷宮、地圖、影像處理等問題上。


上一篇
Day 21|Flood Fill:Java 與 Python 實作 DFS / BFS
系列文
30天 LeetCode 演算法實戰:Java 與 Python 解法比較22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言