DFS
Depth-first search on a 2D grid treats each cell as a node, with edges to its 4 neighbors (up, down, left, right). Starting from any unvisited cell, DFS explores as far as possible before backtracking.
Connected Components
A connected component in a grid is a maximal set of cells that are all reachable from each other via adjacent moves.
Medium1 solutionanalysis
200. Number of Islands
Solutions:
Interactive Visualization
Analysis
- Python
def numIslands(self, grid: List[List[str]]) -> int:
def dfs(row, col):
if not isValidCell(row, col):
return
if not isIsland(row, col) or isVisited(row, col):
return
visited[row][col] = 1
dfs(row + 1, col)
dfs(row, col + 1)
dfs(row - 1, col)
dfs(row, col - 1)
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isVisited = lambda i, j: visited[i][j]
isIsland = lambda i, j: grid[i][j] == "1"
islands_count = 0
m, n = len(grid), len(grid[0])
visited = [[0] * n for _ in range(m)]
for row in range(m):
for col in range(n):
if isIsland(row, col) and not isVisited(row, col):
islands_count += 1
dfs(row, col)
return islands_count
Medium1 solutionanalysis
419. Battleships in a Board
Solutions:
Interactive Visualization
Analysis
- Python
def countBattleships(self, board: List[List[str]]) -> int:
def dfs(row, col):
if not isValidCell(row, col):
return
if not isBattleship(row, col) or isVisited(row, col):
return
visited[row][col] = 1
dfs(row + 1, col)
dfs(row, col + 1)
dfs(row - 1, col)
dfs(row, col - 1)
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isVisited = lambda i, j: visited[i][j]
isBattleship = lambda i, j: board[i][j] == "X"
battleship_count = 0
m, n = len(board), len(board[0])
visited = [[0] * n for _ in range(m)]
for row in range(m):
for col in range(n):
if isBattleship(row, col) and not isVisited(row, col):
battleship_count += 1
dfs(row, col)
return battleship_count
Medium1 solutionanalysis
694. Number of Distinct Islands
Solutions:
Interactive Visualization
Analysis
- Python
def numDistinctIslands(self, grid: List[List[int]]) -> int:
def dfs(row, col, direction):
if not isValidCell(row, col):
return
if not isIsland(row, col) or isVisited(row, col):
return
visited[row][col] = 1
path.append(direction)
dfs(row + 1, col, "D")
dfs(row, col + 1, "R")
dfs(row - 1, col, "U")
dfs(row, col - 1, "L")
path.append("B") # important
m, n = len(grid), len(grid[0])
visited = [[0] * n for i in range(m)]
island_signature = set()
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isVisited = lambda row, col: visited[row][col]
isIsland = lambda row, col: grid[row][col]
for row in range(m):
for col in range(n):
if isIsland(row, col) and not isVisited(row, col):
path = []
dfs(row, col, "S")
island_signature.add(tuple(path))
return len(island_signature)
Easy1 solutionanalysis
733. Flood Fill
Solutions:
Interactive Visualization
Analysis
- Python
def floodFill(
self, image: List[List[int]], sr: int, sc: int, color: int
) -> List[List[int]]:
def dfs(row, col):
if not isValidCell(row, col):
return
if not matchesOriginalColor(row, col) or isVisited(row, col):
return
image[row][col] = color
visited[row][col] = 1
dfs(row + 1, col)
dfs(row, col + 1)
dfs(row - 1, col)
dfs(row, col - 1)
m, n = len(image), len(image[0])
visited = [[0] * n for _ in range(m)]
original_color = image[sr][sc]
matchesOriginalColor = lambda row, col: image[row][col] == original_color
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isVisited = lambda row, col: visited[row][col]
dfs(sr, sc)
return image
Medium1 solutionanalysis
1034. Coloring A Border
Solutions:
Interactive Visualization
Analysis
- Python
def colorBorder(
self, grid: List[List[int]], row: int, col: int, color: int
) -> List[List[int]]:
def dfs(row, col):
if not isValidCell(row, col):
return
if not matchesOriginalColor(row, col) or isVisited(row, col):
return
visited[row][col] = 1
if isBorder(row, col):
borders[row][col] = 1
for r, c in directions:
dfs(row + r, col + c)
m, n = len(grid), len(grid[0])
visited = [[0] * n for _ in range(m)]
borders = [[0] * n for _ in range(m)]
original_color = grid[row][col]
directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]
isVisited = lambda row, col: visited[row][col] == 1
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
matchesOriginalColor = (
lambda row, col: isValidCell(row, col) and grid[row][col] == original_color
)
isBorder = lambda row, col: any(
not matchesOriginalColor(row + r, col + c) for r, c in directions
)
dfs(row, col)
for row in range(m):
for col in range(n):
if borders[row][col] == 1:
grid[row][col] = color
return grid
Easy1 solutionanalysis
463. Island Perimeter
Solutions:
Interactive Visualization
Analysis
- Python
def islandPerimeter(self, grid: List[List[int]]) -> int:
def dfs(row, col):
nonlocal perimeter
if not isValidCell(row, col):
return
if not isIsland(row, col) or isVisited(row, col):
return
visited[row][col] = 1
perimeter += 4 - neighbors(row, col)
for r, c in directions:
dfs(row + r, col + c)
m, n = len(grid), len(grid[0])
visited = [[0] * n for _ in range(m)]
directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]
perimeter = 0
isVisited = lambda row, col: visited[row][col]
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isIsland = lambda row, col: isValidCell(row, col) and grid[row][col]
neighbors = lambda row, col: sum(isIsland(row + r, col + c) for r, c in directions)
for row in range(m):
for col in range(n):
if isIsland(row, col) and not isVisited(row, col):
dfs(row, col)
return perimeter
Medium1 solutionanalysis
695. Max Area of Island
Solutions:
Interactive Visualization
Analysis
- Python
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
def dfs(row, col):
if not isValidCell(row, col):
return
if not isIsland(row, col) or isVisited(row, col):
return
visited[row][col] = 1
areas[-1] += 1
for r, c in directions:
dfs(row + r, col + c)
m, n = len(grid), len(grid[0])
visited = [[0] * n for _ in range(m)]
directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]
areas = [0]
isVisited = lambda row, col: visited[row][col]
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isIsland = lambda row, col: grid[row][col]
for row in range(m):
for col in range(n):
if isIsland(row, col) and not isVisited(row, col):
areas.append(0)
dfs(row, col)
return max(areas)
Medium1 solutionanalysis
3619. Count Islands With Total Value Divisible by K
Solutions:
Interactive Visualization
Analysis
- Python
def countIslands(self, grid: List[List[int]], k: int) -> int:
def dfs(row, col):
nonlocal total
if not isValidCell(row, col):
return
if not isIsland(row, col) or isVisited(row, col):
return
visited[row][col] = 1
total += grid[row][col]
dfs(row + 1, col)
dfs(row, col + 1)
dfs(row - 1, col)
dfs(row, col - 1)
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isVisited = lambda i, j: visited[i][j]
isIsland = lambda i, j: grid[i][j] > 0
islands_count = total = 0
m, n = len(grid), len(grid[0])
visited = [[0] * n for _ in range(m)]
for row in range(m):
for col in range(n):
if isIsland(row, col) and not isVisited(row, col):
total = 0
dfs(row, col)
islands_count += total % k == 0
return islands_count
Medium1 solutionanalysis
1254. Number of Closed Islands
Solutions:
Interactive Visualization
Analysis
- Python
def closedIsland(self, grid: List[List[int]]) -> int:
def dfs(row, col):
nonlocal isBorder
if not isValidCell(row, col):
isBorder = True
return
if not isLand(row, col) or isVisited(row, col):
return
visited[row][col] = 1
dfs(row + 1, col)
dfs(row, col + 1)
dfs(row - 1, col)
dfs(row, col - 1)
m, n = len(grid), len(grid[0])
visited = [[0] * n for _ in range(m)]
count = 0
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isLand = lambda row, col: grid[row][col] == 0
isVisited = lambda row, col: visited[row][col]
for row in range(m):
for col in range(n):
if isLand(row, col) and not isVisited(row, col):
isBorder = False
dfs(row, col)
count += not isBorder
return count
Medium1 solutionanalysis
1905. Count Sub Islands
Solutions:
Interactive Visualization
Analysis
- Python
def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int:
def dfs(row, col):
nonlocal isSubIsland
if not isValidCell(row, col):
return
if not isIsland(row, col) or isVisited(row, col):
return
visited[row][col] = 1
if grid1[row][col] == 0:
isSubIsland = False
dfs(row + 1, col)
dfs(row, col + 1)
dfs(row - 1, col)
dfs(row, col - 1)
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isVisited = lambda i, j: visited[i][j]
isIsland = lambda i, j: grid2[i][j] == 1
sub_islands_count = 0
m, n = len(grid2), len(grid2[0])
visited = [[0] * n for _ in range(m)]
for row in range(m):
for col in range(n):
if isIsland(row, col) and not isVisited(row, col):
isSubIsland = True
dfs(row, col)
sub_islands_count += isSubIsland
return sub_islands_count
Hard1 solutionanalysis
827. Making A Large Island
Solutions:
Interactive Visualization
Analysis
- Python
def largestIsland(self, grid: List[List[int]]) -> int:
def dfs(row, col):
if not isValidCell(row, col):
return
if not isIsland(row, col) or isVisited(row, col):
return
visited[row][col] = island_id
island_size[island_id] += 1
for r, c in directions:
dfs(row + r, col + c)
def getUniqueNeighborsSum(row, col):
ids = set()
for r, c in directions:
if isValidCell(row + r, col + c):
ids.add(visited[row + r][col + c])
return sum(island_size[i] for i in ids)
m, n = len(grid), len(grid[0])
visited = [[0] * n for _ in range(m)]
island_size = collections.Counter()
directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]
largest_island = 0
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isVisited = lambda row, col: visited[row][col] > 0
isIsland = lambda row, col: grid[row][col] == 1
island_id = largest_island = 0
for row in range(m):
for col in range(n):
if isIsland(row, col) and not isVisited(row, col):
island_id += 1
dfs(row, col)
for row in range(m):
for col in range(n):
if not isIsland(row, col):
largest_island = max(
largest_island, getUniqueNeighborsSum(row, col) + 1
)
return largest_island or m * n
Surrounded Regions
Medium1 solutionanalysis
130. Surrounded Regions
Solutions:
Interactive Visualization
Analysis
- Python
def solve(self, board: List[List[str]]) -> None:
def dfs(row, col):
if not isValidCell(row, col) or not isRegion(row, col):
return
board[row][col] = "B"
dfs(row + 1, col)
dfs(row, col + 1)
dfs(row - 1, col)
dfs(row, col - 1)
m, n = len(board), len(board[0])
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isRegion = lambda row, col: board[row][col] == "O"
for row in range(m):
dfs(row, 0)
dfs(row, n - 1)
for col in range(n):
dfs(0, col)
dfs(m - 1, col)
for row in range(m):
for col in range(n):
match board[row][col]:
case "B":
board[row][col] = "O"
case "O":
board[row][col] = "X"
Medium1 solutionanalysis
417. Pacific Atlantic Water Flow
Solutions:
Interactive Visualization
Analysis
- Python
def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
def dfs(row, col, prev=0):
if not isValidCell(row, col):
return
if prev > heights[row][col] or isVisited(row, col):
return
visited[row][col] = current_visit
reachability[row][col] += current_visit
dfs(row + 1, col, heights[row][col])
dfs(row, col + 1, heights[row][col])
dfs(row - 1, col, heights[row][col])
dfs(row, col - 1, heights[row][col])
m, n = len(heights), len(heights[0])
reachability = [[0] * n for _ in range(m)]
visited = [[0] * n for _ in range(m)]
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isVisited = lambda row, col: visited[row][col] == current_visit
current_visit = 2
for row in range(m):
dfs(row, 0)
for col in range(n):
dfs(0, col)
current_visit = 3
for row in range(m):
dfs(row, n - 1)
for col in range(n):
current_visit = 3
dfs(m - 1, col)
results = []
for row in range(m):
for col in range(n):
if reachability[row][col] == 5:
results.append([row, col])
return results
Medium1 solutionanalysis
1020. Number of Enclaves
Solutions:
Interactive Visualization
Analysis
- Python
def numEnclaves(self, grid: List[List[int]]) -> int:
def dfs(row, col):
if not isValidCell(row, col):
return
if not isLand(row, col) or isVisited(row, col):
return
visited[row][col] = 1
dfs(row + 1, col)
dfs(row, col + 1)
dfs(row - 1, col)
dfs(row, col - 1)
m, n = len(grid), len(grid[0])
visited = [[0] * n for _ in range(m)]
count = 0
isValidCell = lambda row, col: (0 <= row < m) and (0 <= col < n)
isLand = lambda row, col: grid[row][col] == 1
isVisited = lambda row, col: visited[row][col]
for row in range(m):
dfs(row, 0)
dfs(row, n - 1)
for col in range(n):
dfs(0, col)
dfs(m - 1, col)
for row in range(m):
for col in range(n):
if isLand(row, col) and not isVisited(row, col):
count += 1
return count