目錄
- 任務
- 200. 島嶼數量
- 思路
- 695. 島嶼的最大面積
- 思路
- 200. 島嶼數量
任務
200. 島嶼數量
給你一個由 '1'(陸地)和 '0'(水)組成的的二維網格,請你計算網格中島嶼的數量。
島嶼總是被水包圍,並且每座島嶼只能由水平方向和/或豎直方向上相鄰的陸地連線形成。
此外,你可以假設該網格的四條邊均被水包圍。
思路
總的邏輯是,每遇到一個新的島嶼,就將計數加1,具體的遍歷格子則使用dfs和bfs去遍歷陸地,對於每一個格子,都進行dfs或bfs的遍歷,
- 當前為水,不統計計數,繼續下一個格子的處理
- 當前為已經遍歷過的島嶼,不統計計數,繼續下一個格子的處理
- 遇到新大陸(未訪問過的大陸格子),則對該格子進行遍歷以找到與該格子相關的整個島嶼
具體單個島嶼的遍歷,實現既可以用dfs,也可以用bfs。
對於dfs,每遇到新的格子(未訪問過的)且為陸地則標記並遞迴遍歷,這裡隱含著,如果遇到不是陸地的地方則進行下一個方向的處理。如此,可以訪問一個整島嶼,將其相關格子標記為True。
對於bfs,實際與bfs同理,只是遍歷的流程是按照層去遍歷,也是遍歷一整個島嶼,將整個島嶼的格子標記為True。需要注意的點是,在每次加入佇列時,都需要標記格子為True,原因是為了不重複訪問,節省時間,具體更詳細的原因可以去看第十一章 圖論 Part1的內容。
下面給出dfs和bfs解決這個問題的程式碼
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
visited = [[False] * len(grid[0]) for _ in range(len(grid))]
result = 0
for i in range(len(grid)): #以每個格子為起點進行遍歷
for j in range(len(grid[0])):
if visited[i][j]==False and grid[i][j] == '1': #為新大陸時,累加結果
result += 1
#self.dfs(grid,visited,i,j) #按深度優先遍歷標記某島嶼
self.bfs(grid,visited,i,j) #按深度優先遍歷標記某島嶼
return result
def dfs(self,grid,visited,x,y):
dir = [(1,0),(0,1),(-1,0),(0,-1)] #逆時針四個方向
visited[x][y] = True # 由呼叫者(包含外部和自身)保證了該格子為訪問過的陸地!
for i in range(4):
nextX = x + dir[i][0]
nextY = y + dir[i][1]
if nextX < 0 or nextY<0 or nextX>=len(grid) or nextY>=len(grid[0]):
continue
if visited[nextX][nextY] == False and grid[nextX][nextY] == '1':
self.dfs(grid,visited,nextX,nextY)
from collections import deque
def bfs(self,grid,visited,x,y):
dir = [(1,0),(0,1),(-1,0),(0,-1)] #逆時針四個方向
que = deque()
que.append((x,y))
visited[x][y] = True
while(que):
curX,curY = que.popleft()
for i in range(4):
nextX = curX + dir[i][0]
nextY = curY + dir[i][1]
if nextX < 0 or nextY<0 or nextX>=len(grid) or nextY>=len(grid[0]):
continue
if visited[nextX][nextY] == False and grid[nextX][nextY] == '1':
que.append((nextX,nextY))
visited[nextX][nextY] =True
695. 島嶼的最大面積
給你一個大小為 m x n 的二進位制矩陣 grid 。
島嶼 是由一些相鄰的 1 (代表土地) 構成的組合,這裡的「相鄰」要求兩個 1 必須在 水平或者豎直的四個方向上 相鄰。你可以假設 grid 的四個邊緣都被 0(代表水)包圍著。
島嶼的面積是島上值為 1 的單元格的數目。
計算並返回 grid 中最大的島嶼面積。如果沒有島嶼,則返回面積為 0 。
思路
如果理解了上一題,本題就可以直接解決,本題求的是島嶼面積,累計的值就是某一個島嶼的面積,就在dfs或者bfs中累計,然後在主函式中取最大的島嶼面積即可。
下面給出dfs和bfs的方法
class Solution:
def __init__(self):
self.count = 0
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
visited = [[False] * len(grid[0]) for _ in range(len(grid))]
result = 0
for i in range(len(grid)): #以每個格子為起點進行遍歷
for j in range(len(grid[0])):
if visited[i][j]==False and grid[i][j] == 1: #為新大陸時,累加結果
self.count = 0
#self.dfs(grid,visited,i,j) #按深度優先遍歷標記某島嶼
self.bfs(grid,visited,i,j) #按深度優先遍歷標記某島嶼
result = max(result,self.count)
return result
def dfs(self,grid,visited,x,y):
dir = [(1,0),(0,1),(-1,0),(0,-1)] #逆時針四個方向
visited[x][y] = True # 由呼叫者(包含外部和自身)保證了該格子為訪問過的陸地!
self.count += 1
for i in range(4):
nextX = x + dir[i][0]
nextY = y + dir[i][1]
if nextX < 0 or nextY<0 or nextX>=len(grid) or nextY>=len(grid[0]):
continue
if visited[nextX][nextY] == False and grid[nextX][nextY] == 1: #未訪問過的陸地則繼續訪問(直到遍歷完整個單獨的島嶼)
self.dfs(grid,visited,nextX,nextY)
from collections import deque
def bfs(self,grid,visited,x,y):
dir = [(1,0),(0,1),(-1,0),(0,-1)] #逆時針四個方向
que = deque()
que.append((x,y))
visited[x][y] = True
self.count += 1
while(que):
curX,curY = que.popleft()
for i in range(4):
nextX = curX + dir[i][0]
nextY = curY + dir[i][1]
if nextX < 0 or nextY<0 or nextX>=len(grid) or nextY>=len(grid[0]):
continue
if visited[nextX][nextY] == False and grid[nextX][nextY] == 1: #未訪問過的陸地則繼續訪問(直到遍歷完整個單獨的島嶼)
que.append((nextX,nextY))
visited[nextX][nextY] =True
self.count+=1