# **Leetcode筆記(Number of Islands)** :::info :information_source: 題目 : Number of Islands, 類型 : graph , 等級 : medium 日期 : 2023/04/15,2023/05/16,2023/07/13,2023/09/16,2023/11/20,2023/11/25,2024/02/13,2024/10/24,2025/02/17 ::: ### 嘗試 2023/05/16 時間複雜度是 O(m * n),其中 m 是矩陣的行數,n 是矩陣的列數。因為我們需要遍歷整個矩陣 空間複雜度是 O(m * n) ```python dfs (stack) class Solution: def numIslands(self, grid: List[List[str]]) -> int: m, n = len(grid), len(grid[0]) dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)] record = [] visited = set() def dfs(r, c): while record: row, col = record.pop() visited.add((row, col)) for dr, dc in dirs: nr, nc = row + dr, col + dc if (0 <= nr < m and 0 <= nc < n and grid[nr][nc] == "1" and (nr, nc) not in visited): record.append((nr, nc)) visited.add((nr, nc)) res = 0 # 因為不連續 所以另外要用一個迴圈 for r in range(m): for c in range(n): # 這樣被第一個node連著都在visited if grid[r][c] == "1" and (r, c) not in visited: # 初始化 record.append([r, c]) dfs(r, c) res += 1 return res ``` 2023/05/16 ```python bfs (queue) class Solution: def numIslands(self, grid: List[List[str]]) -> int: # bfs (queue) m, n = len(grid), len(grid[0]) dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)] q = deque() visited = set() def bfs(r, c): while q: row, col = q.popleft() visited.add((row, col)) for dr, dc in dirs: nr, nc = row + dr, col + dc if (0 <= nr < m and 0 <= nc < n and grid[nr][nc] == "1" and (nr, nc) not in visited): q.append((nr, nc)) visited.add((nr, nc)) res = 0 for r in range(m): for c in range(n): if grid[r][c] == "1" and (r, c) not in visited: # 初始化 q.append([r, c]) bfs(r, c) res += 1 return res ``` 2023/07/13 ```python class Solution: def numIslands(self, grid: List[List[str]]) -> int: m, n = len(grid), len(grid[0]) visited = set() dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)] count = 0 def dfs(r, c): if r < 0 or c < 0 or r >= m or c >=n or (r, c) in visited or grid[r][c] == "0": return visited.add((r, c)) for dr, dc in dirs: nr, nc = r + dr, c + dc dfs(nr, nc) return for r in range(m): for c in range(n): if grid[r][c] == "1" and (r, c) not in visited: dfs(r, c) count += 1 return count ``` 2023/09/16 不能直接船grid[nr][nc],如果nr nc這時候本身就超過範圍,那就會錯誤 要先檢查範圍再取grid的值 ```python class Solution: def numIslands(self, grid: List[List[str]]) -> int: dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)] m, n = len(grid), len(grid[0]) count = 0 visited = set() def bfs(r, c): if r < 0 or c < 0 or r >= m or c >= n or grid[r][c] == "0" or (r, c) in visited: return False visited.add((r, c)) for dr, dc in dirs: nr, nc = r + dr, c + dc bfs(nr, nc) return True for r in range(m): for c in range(n): if bfs(r, c): count += 1 return count ``` 2023/11/20 ```python class Solution: def numIslands(self, grid: List[List[str]]) -> int: visited = set() dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)] res = 0 R, C = len(grid), len(grid[0]) def bfs(r, c): if r < 0 or r >= R or c < 0 or c >= C or grid[r][c] == "0" or (r, c) in visited: return False visited.add((r,c)) for dr, dc in dirs: nr, nc = r + dr, c + dc bfs(nr, nc) return True for r in range(R): for c in range(C): if bfs(r, c): res += 1 return res ``` 2023/11/25 ```python class Solution: def numIslands(self, grid: List[List[str]]) -> int: n, m = len(grid), len(grid[0]) res = 0 visited = set() dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)] def bfs(r, c, grid): if r < 0 or c < 0 or r >= n or c >= m or (r, c) in visited or grid[r][c] == "0": return False visited.add((r, c)) for dr, dc in dirs: nr, nc = r + dr, c + dc bfs(nr, nc, grid) return True for r in range(n): for c in range(m): if bfs(r, c, grid): res += 1 return res ``` 2024/02/13 ```python class Solution: def numIslands(self, grid: List[List[str]]) -> int: visited = set() res = 0 dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)] n, m = len(grid), len(grid[0]) def bfs(r, c): if r < 0 or c < 0 or r >= n or c >= m or (r, c) in visited or grid[r][c] == "0": return visited.add((r, c)) for dr, dc in dirs: nr, nc = r + dr, c + dc bfs(nr, nc) return True for r in range(n): for c in range(m): if bfs(r, c): res += 1 return res ``` 2024/10/24 ```python class Solution: def numIslands(self, grid: List[List[str]]) -> int: self.res = 0 self.n, self.m = len(grid), len(grid[0]) self.dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)] self.visited = set() for r in range(self.n): for c in range(self.m): if self.dfs(grid, r, c): self.res += 1 return self.res def dfs(self, grid, r, c): if r < 0 or r >= self.n or c < 0 or c >= self.m or (r, c) in self.visited or grid[r][c] == "0": return self.visited.add((r, c)) for dr, dc in self.dirs: nr, nc = r + dr, c + dc self.dfs(grid, nr, nc) return True ``` 2024/10/24 面試Google前準備,dfs / bfs 加油!! ```python # bfs class Solution: def numIslands(self, grid: List[List[str]]) -> int: self.n, self.m = len(grid), len(grid[0]) self.dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)] visited = set() res = 0 for r in range(self.n): for c in range(self.m): if grid[r][c] == "1" and (r, c) not in visited: self.bfs(grid, r, c, visited) res += 1 return res def bfs(self, grid, r, c, visited): q = deque() q.append((r, c)) visited.add((r, c)) while q: r, c = q.popleft() for dr, dc in self.dirs: nr, nc = r + dr, c + dc if 0 <= nr < self.n and 0 <= nc < self.m and (nr, nc) not in visited and grid[nr][nc] == "1": visited.add((nr, nc)) q.append((nr, nc)) return ``` ```python # dfs class Solution: def numIslands(self, grid: List[List[str]]) -> int: res = 0 self.n, self.m = len(grid), len(grid[0]) self.dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)] visited = set() for r in range(self.n): for c in range(self.m): if self.dfs(grid, r, c, visited): res += 1 return res def dfs(self, grid, r, c, visited): if r < 0 or r >= self.n or c < 0 or c >= self.m or (r, c) in visited or grid[r][c] == "0": return False visited.add((r, c)) for dr, dc in self.dirs: nr, nc = r + dr, c + dc if 0 <= nr < self.n and 0 <= nc < self.m and (nr, nc) not in visited and grid[nr][nc] == "1": self.dfs(grid, nr, nc, visited) return True ``` 2025/02/17 ```python class Solution: def numIslands(self, grid: List[List[str]]) -> int: self.grid = grid self.n, self.m = len(grid), len(grid[0]) res = 0 self.visited = set() self.dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)] for r in range(self.n): for c in range(self.m): if (r, c) not in self.visited and self.grid[r][c] == "1": self.bfs(r, c) res += 1 return res def bfs(self, r, c): if r < 0 or c < 0 or r >= self.n or c >= self.m or (r, c) in self.visited or self.grid[r][c] == "0": return self.visited.add((r, c)) for dr, dc in self.dirs: nr, nc = r + dr, c + dc self.bfs(nr, nc) ``` --- ### **優化** 時間複雜度O(n),空間複雜度O(n) ```python # dfs class Solution: def numIslands(self, grid: List[List[str]]) -> int: ROW, COL = len(grid), len(grid[0]) visit = set() def dfs(r, c): if (r < 0 or c < 0 or r == ROW or c == COL or grid[r][c] == "0" or (r, c) in visit): return visit.add((r, c)) dfs(r + 1, c) dfs(r - 1, c) dfs(r, c + 1) dfs(r, c - 1) res = 0 for r in range(ROW): for c in range(COL): # 防止已經被連起來的島嶼又被dfs一次 if grid[r][c] == "1" and (r, c) not in visit: dfs(r, c) # 都return(都撞到0了)才會通過此 res += 1 return res ``` ```python # bfs_1 from collections import deque class Solution: def numIslands(self, grid: List[List[str]]) -> int: ROW, COL = len(grid), len(grid[0]) visit = set() # iterative def bfs(r, c): # 初始化 queue = deque([(r, c)]) visit.add((r, c)) while queue: r, c = queue.popleft() directions = [[1, 0], [-1, 0], [0, 1], [0, -1]] for dr, dc in directions: nr, nc = r + dr, c + dc # 取代四點去循環 if (nr < 0 or nc < 0 or nr == ROW or nc == COL or grid[nr][nc] == "0" or (nr, nc) in visit): continue # 跳下一個循環 # 合格的話 queue.append((nr, nc)) visit.add((nr, nc)) res = 0 for r in range(ROW): for c in range(COL): if grid[r][c] == "1" and (r, c) not in visit: bfs(r, c) # q為空才會通過此 res += 1 return res ``` ```python # bfs_2 from collections import deque class Solution: def numIslands(self, grid: List[List[str]]) -> int: ROW, COL = len(grid), len(grid[0]) visit = set() # iterative def bfs(r, c): # 初始化 queue = deque([(r, c)]) #visit.add((row, col)) while queue: r, c = queue.popleft() if (r, c) not in visit: visit.add((r, c)) if r - 1 >= 0 and grid[r - 1][c] == '1': queue.append((r - 1, c)) if r + 1 < ROW and grid[r + 1][c] == '1': queue.append((r + 1, c)) if c - 1 >= 0 and grid[r][c - 1] == '1': queue.append((r, c - 1)) if c + 1 < COL and grid[r][c + 1] == '1': queue.append((r, c + 1)) res = 0 for r in range(ROW): for c in range(COL): if grid[r][c] == "1" and (r, c) not in visit: bfs(r, c) # q為空才會通過此 res += 1 return res ``` --- **:warning: 錯誤語法** :::warning q為append ::: **:thumbsup:學習** :::success ::: **思路** **講解連結** https://www.youtube.com/watch?v=pV2kpPD66nE Provided by. NeetCode https://blog.csdn.net/qq_37821701/article/details/108414557 https://blog.csdn.net/fuxuemingzhu/article/details/81126995 ###### tags: `graph` `medium` `leetcode`