200.島嶼數量
給定一個由 ‘1’(陸地)和 ‘0’(水)組成的的二維網格,計算島嶼的數量。一個島被水包圍,並且它是通過水平方向或垂直方向上相鄰的陸地連接而成的。你可以假設網格的四個邊均被水包圍。
示例 1:
輸入:
11110
11010
11000
00000
輸出: 1
from typing import List
class Solution:
# x-1,y
# x,y-1 x,y x,y+1
# x+1,y
# 方向數組,它表示了相對於當前位置的 4 個方向的橫、縱座標的偏移量,這是一個常見的技巧
directions = [(-1, 0), (0, -1), (1, 0), (0, 1)]
def numIslands(self, grid: List[List[str]]) -> int:
m = len(grid)
# 特判
if m == 0:
return 0
n = len(grid[0])
#m是row
marked = [[False for _ in range(n)] for _ in range(m)]
count = 0
# 從第 1 行、第 1 格開始,對每一格嘗試進行一次 DFS 操作
for i in range(m):#行
for j in range(n):#列
# 只要是陸地,且沒有被訪問過的,就可以使用 DFS 發現與之相連的陸地,並進行標記
if not marked[i][j] and grid[i][j] == '1':
# count 可以理解爲連通分量,你可以在深度優先遍歷完成以後,再計數,
# 即這行代碼放在【位置 1】也是可以的
count += 1
self.__dfs(grid, i, j, m, n, marked)
# 【位置 1】
return count
def __dfs(self, grid, i, j, m, n, marked):
marked[i][j] = True
for direction in self.directions: # directions = [(-1, 0), (0, -1), (1, 0), (0, 1)]
new_i = i + direction[0]
new_j = j + direction[1]
if 0 <= new_i < m and 0 <= new_j < n and not marked[new_i][new_j] and grid[new_i][new_j] == '1':
self.__dfs(grid, new_i, new_j, m, n, marked)
if __name__ == '__main__':
grid = [['1', '1', '1', '1', '0'],
['1', '1', '0', '1', '0'],
['1', '1', '0', '0', '0'],
['0', '0', '0', '0', '0']]
solution = Solution()
result = solution.numIslands(grid)
print(result)
時間複雜度:O(MN),其中 MM 和 NN 分別爲行數和列數。
空間複雜度:O(MN),在最壞情況下,整個網格均爲陸地,深度優先搜索的深度達到 MN
695.最大島嶼
島嶼是由1組成,但是得滿足一些條件。比如一個1的上下左右都算法島嶼的面積,而斜側(左上,左下,右上,右下)不算。
我們對地圖中的點進行遍歷,如果這個點爲0,返回0,如果爲1,統計這個島嶼的面積。
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
m = len(grid)
n = len(grid[0])
ans = 0
def dfs(i, j):
if 0<=i<m and 0<=j<n and grid[i][j]:
grid[i][j] = 0 # 因爲grid[i][j]是1,所以面積至少是1
return 1 + dfs(i-1,j)+dfs(i+1,j)+dfs(i,j-1)+dfs(i,j+1)
return 0
for i in range(0,m):
for j in range(0,n):
ans = max(ans, dfs(i,j))
return ans