給定乙個由 '1'(陸地)和 '0'(水)組成的的二維網格,計算島嶼的數量。乙個島被水包圍,並且它是通過水平方向或垂直方向上相鄰的陸地連線而成的。你可以假設網格的四個邊均被水包圍。
示例 1:
輸入:11110
11010
11000
00000
輸出: 1
思路
線性掃瞄整個二維網格,如果乙個結點包含 1,則以其為根結點啟動廣度優先搜尋。將其放入佇列中,並將值設為 0 以標記訪問過該結點。迭代地搜尋佇列中的每個結點,直到隊列為空。
偶的
class solution:
def numislands(self, grid: list[list[str]]) -> int:
if not grid or not grid[0]:
return 0
res = 0
queue =
m, n = len(grid), len(grid[0])
marked = [[false for _ in range(n)] for _ in range(m)]
print(m,n)
for i in range(m):
for j in range(n):
# 只要是陸地,且沒有被訪問過的,就可以使用 bfs 發現與之相連的陸地,並進行標記
if not marked[i][j] and grid[i][j]=='1':
res+=1
marked[i][j] = true
while queue:
a,b = queue.pop(0)
dx = [-1,0,1,0]
dy = [0,1,0,-1]
for z in range(4):
x = a+dx[z]
y = b+dy[z]
# 如果不越界、沒有被訪問過、並且還要是陸地,我就繼續放入佇列,放入佇列的同時,要記得標記已經訪問過
if m>x>=0 and n>y>=0 and not marked[x][y] and grid[x][y]=='1':
marked[x][y] = true
return res
參考
from typing import list
from collections import deque
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])
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):
# 只要是陸地,且沒有被訪問過的,就可以使用 bfs 發現與之相連的陸地,並進行標記
if not marked[i][j] and grid[i][j] == '1':
# count 可以理解為連通分量,你可以在廣度優先遍歷完成以後,再計數,
# 即這行**放在【位置 1】也是可以的
count += 1
queue = deque()
# 注意:這裡要標記上已經訪問過
marked[i][j] = true
while queue:
cur_x, cur_y = queue.popleft()
# 得到 4 個方向的座標
for direction in self.directions:
new_i = cur_x + direction[0]
new_j = cur_y + 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':
#【特別注意】在放入佇列以後,要馬上標記成已經訪問過,語義也是十分清楚的:反正只要進入了佇列,你遲早都會遍歷到它
# 而不是在出佇列的時候再標記
#【特別注意】如果是出佇列的時候再標記,會造成很多重複的結點進入佇列,造成重複的操作,這句話如果你沒有寫對地方,**會嚴重超時的
marked[new_i][new_j] = true
#【位置 1】
return count
if __name__ == '__main__':
grid = [['1', '1', '1', '1', '0'],
['1', '1', '0', '1', '0'],
['1', '1', '0', '0', '0'],
['0', '0', '0', '0', '0']]
感染的方法,參考
class solution:
def numislands(self, grid: list[list[str]]) -> int:
if not grid or not grid[0]:
return 0
res = 0
m, n = len(grid), len(grid[0])
d = [(0, 1), (0, -1), (1, 0), (-1, 0)]
for i in range(m):
for j in range(n):
if grid[i][j] == '1':
grid[i][j] = '#'
res += 1
queue = [(i, j)]
while queue:
a, b = queue.pop(0)
for dx, dy in d:
x = a + dx
y = b + dy
if 0 <= x < m and 0 <= y < n and grid[x][y] == '1':
grid[x][y] = '#'
return res
LeetCode 200 島嶼數量
給定乙個由 1 陸地 和 0 水 組成的的二維網格,計算島嶼的數量。乙個島被水包圍,並且它是通過水平方向或垂直方向上相鄰的陸地連線而成的。你可以假設網格的四個邊均被水包圍。示例 1 輸入 11110 11010 11000 00000輸出 1 示例 2 輸入 11000 11000 00100 00...
leetcode200 島嶼數量
可以遍歷矩陣中的每個位置,如果遇到1就將與其相連的一片1都感染成2 dfs 並自增島數量。class solution object def numislands self,grid type grid list list str rtype int res 0 if not grid return...
Leetcode 200 島嶼數量
給定乙個由 1 陸地 和 0 水 組成的的二維網格,計算島嶼的數量。乙個島被水包圍,並且它是通過水平方向或垂直方向上相鄰的陸地連線而成的。你可以假設網格的四個邊均被水包圍。示例 1 輸入 11110 11010 11000 00000 輸出 1示例 2 輸入 11000 11000 00100 00...