解析
130. Surrounded Regions
ref
- https://neetcode.io/problems/surrounded-regions
- https://www.youtube.com/watch?v=9z2BunfoZ5Y&ab_channel=NeetCode
133. Clone Graph
- 用 DFS 不断地递归创建未创建过的节点
- 如果已经创建过了,直接从 oldToNew 里返回新节点
- DFS/BFS 的区别是先创建最 deepth 的节点还是先创建最 close 的节点
# DFS
# - time: O(nodes + edges)
# - space: O(nodes), oldToNew 用了 O(nodes),calling stack for recursion 用了 O(nodes)
def cloneGraph(self, node):
"""
:type node: Node
:rtype: Node
"""
oldToNew = {}
def dfs(oldNode):
if oldNode in oldToNew:
return oldToNew[oldNode]
newNode = Node(oldNode.val)
oldToNew[oldNode] = newNode
for neighbor in oldNode.neighbors:
newNode.neighbors.append(dfs(neighbor))
return newNode
if not node:
return None
return dfs(node)
# BFS
# - time: O(nodes + edges)
# - space: O(nodes)
def cloneGraph(self, node):
"""
:type node: Node
:rtype: Node
"""
if not node:
return None
oldToNew = {node: Node(node.val)}
queue = [node]
while queue:
oldNode = queue.pop(0)
for nei in oldNode.neighbors:
if nei not in oldToNew:
newNei = Node(nei.val)
oldToNew[nei] = newNei
queue.append(nei)
oldToNew[oldNode].neighbors.append(oldToNew[nei])
return oldToNew[node]
ref
- https://neetcode.io/problems/clone-graph
- https://www.youtube.com/watch?v=mQeF6bN8hMk&ab_channel=NeetCode
200. Number of Islands
- 用一个 set 记录已经访问过的节点,然后用 DFS/BFS 不断去寻找 island,直到所有节点都被访问了
- 可以优化成 访问过的"1"节点置为 “0”,从而不需要 visit
# BFS
# - time: O(m*n)
# - space: O(m*n)
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
if len(grid) == 0:
return 0
visit = set()
islands = 0
ROW, COL = len(grid), len(grid[0])
def bfs(r, c):
queue = [(r, c)]
visit.add((r, c))
while queue:
r, c = queue.pop(0)
directions = [[0, -1], [0, 1], [1, 0], [-1, 0]]
# BFS 去访问上下左右的元素
for direction in directions:
newR, newC = r + direction[0], c + direction[1]
if (0 <= newR < ROW and
0 <= newC < COL and
(newR, newC) not in visit and
grid[newR][newC] == "1"):
queue.append((newR, newC))
visit.add((newR, newC))
for row in range(ROW):
for col in range(COL):
if grid[row][col] == "1" and (row, col) not in visit:
bfs(row, col)
islands += 1
return islands
# DFS - 使用 visit
# - time: O(m*n)
# - space: O(m*n), visit 使用了 O(m*n)
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
if len(grid) == 0:
return 0
visit = set()
islands = 0
ROW, COL = len(grid), len(grid[0])
def dfs(r, c):
if r < 0 or r == ROW or c < 0 or c == COL or grid[r][c] == "0" or (r, c) in visit:
return
visit.add((r, c))
directions = [[0, -1], [0, 1], [-1, 0], [1, 0]]
for direction in directions:
newRow, newCol = r + direction[0], c + direction[1]
dfs(newRow, newCol)
for row in range(ROW):
for col in range(COL):
if grid[row][col] == "1" and (row, col) not in visit:
dfs(row, col)
islands += 1
return islands
# DFS - 不使用 visit
# - time: O(m*n)
# - space: O(m*n), recursion stack uses o(m*n)
class Solution(object):
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
islands = 0
ROW = len(grid)
COL = len(grid[0])
directions = [[-1, 0], [1, 0], [0, 1], [0, -1]]
def dfs(row, col):
if row < 0 or row >= ROW or col < 0 or col >= COL or grid[row][col] == "0":
return
grid[row][col] = "0" # 把已经访问过island的土地置为"0",已标识该土地已经被访问过了
for direction in directions:
newRow = direction[0] + row
newCol = direction[1] + col
dfs(newRow, newCol)
for r in range(ROW):
for c in range(COL):
if grid[r][c] == "1": # 只有发现 island 时,才 dfs
# dfs 把该岛屿的所有土地都置为 "0",然后更新 islands
dfs(r, c)
islands += 1
return islands
ref
695. Max Area of Island
- 用一个 set 记录已经访问过的节点,然后用 DFS/BFS 不断去寻找 island 并计算每个已访问 island 的大小,直到所有节点都被访问了
- 可以优化成 访问过的"1"节点置为 “0”,从而不需要 visit
# BFS
# - time: O(m*n)
# - space: O(m*n)
def maxAreaOfIsland(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
visit = set()
res = 0
ROW, COL = len(grid), len(grid[0])
def bfs(row, col):
maxArea = 1
queue = [(row, col)]
visit.add((row, col))
directions = [[0, -1], [0, 1], [-1, 0], [1, 0]]
while queue:
r, c = queue.pop(0)
for direction in directions:
newRow, newCol = r + direction[0], c + direction[1]
if 0 <= newRow < ROW and 0 <= newCol < COL and grid[newRow][newCol] == 1 and (
newRow, newCol) not in visit:
maxArea += 1
visit.add((newRow, newCol))
queue.append((newRow, newCol))
return maxArea
for row in range(ROW):
for col in range(COL):
if grid[row][col] == 1 and (row, col) not in visit:
res = max(res, bfs(row, col))
return res
# DFS
# - time: O(m*n)
# - space: O(m*n)
def maxAreaOfIsland(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
visit = set()
res = 0
ROW, COL = len(grid), len(grid[0])
def dfs(row, col):
if row < 0 or row == ROW or col < 0 or col == COL or (row, col) in visit or grid[row][col] == 0:
return 0
visit.add((row, col))
return (1
+ dfs(row + 1, col)
+ dfs(row - 1, col)
+ dfs(row, col + 1)
+ dfs(row, col - 1)
)
for row in range(ROW):
for col in range(COL):
if grid[row][col] == 1 and (row, col) not in visit:
res = max(res, dfs(row, col))
return res
ref
- https://neetcode.io/problems/max-area-of-island
- http://youtube.com/watch?v=iJGr1OtmH0c&ab_channel=NeetCode
286 · Walls and Gates
ref
417. Pacific Atlantic Water Flow
ref
- https://neetcode.io/problems/pacific-atlantic-water-flow
- https://www.youtube.com/watch?v=s-VkcjHqkGI
684. Redundant Connection
ref
994. Rotting Oranges
ref