leetcode 200 島嶼數量

2021-09-26 15:30:07 字數 3394 閱讀 7273

給定乙個由 '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...