Een matrix is gewoon een 2D-array, maar in interviews stelt het vaak een grid voor - een kaart, een bord of een doolhof. Elke cel grid[r][c] is een knooppunt, en de buren zijn aangrenzende cellen.
grid = [
[1, 1, 0],
[1, 0, 0],
[0, 0, 1]
]
Rij r, kolom c, afmetingen m × n. Eenvoudig - maar de patronen die erop gebouwd worden zijn krachtig.
In plaats van vier aparte if-statements, gebruik een richtingsarray:
# 4 richtingen (boven, onder, links, rechts)
dirs = [(-1,0), (1,0), (0,-1), (0,1)]
# 8 richtingen (inclusief diagonalen)
dirs = [(-1,0),(1,0),(0,-1),(0,1),
(-1,-1),(-1,1),(1,-1),(1,1)]
for dr, dc in dirs:
nr, nc = r + dr, c + dc
if 0 <= nr < m and 0 <= nc < n:
# verwerk buur
Dit is het meest herbruikbare stukje code in gridproblemen.
BFS vindt het kortste pad in een ongewogen grid. Begin bij de bron, verken alle buren op afstand 1, dan afstand 2, enzovoort.
from collections import deque
def shortest_path(grid, start, end):
m, n = len(grid), len(grid[0])
q = deque([(start[0], start[1], 0)])
visited = {(start[0], start[1])}
dirs = [(-1,0),(1,0),(0,-1),(0,1)]
while q:
r, c, dist = q.popleft()
if (r, c) == end:
return dist
for dr, dc in dirs:
nr, nc = r+dr, c+dc
if 0<=nr<m and 0<=nc<n and (nr,nc) not in visited and grid[nr][nc]==0:
visited.add((nr, nc))
q.append((nr, nc, dist+1))
return -1
Flood fill (zoals het verfemmertje): vanaf een startcel verander je alle verbonden cellen met dezelfde kleur. DFS of BFS werken beide.
Sign in to join the discussion
Aantal Eilanden: scan het grid; als je een 1 vindt, voer DFS/BFS uit om het hele eiland als bezocht te markeren, en verhoog je teller.
def num_islands(grid):
count = 0
for r in range(len(grid)):
for c in range(len(grid[0])):
if grid[r][c] == '1':
dfs(grid, r, c) # markeer eiland
count += 1
return count
Waarom markeren we bij 'Aantal Eilanden' cellen als bezocht tijdens DFS?
Alle aanvankelijk rotte sinaasappels zijn bronnen. Zet ze allemaal in de queue op tijdstip 0, dan BFS. Elk niveau is één minuut. Als de queue leeg is, controleer of er verse sinaasappels overblijven.
Minuut 0: [2, 1, 1] 2 = rot, 1 = vers
[1, 1, 0]
[0, 1, 1]
Minuut 4: [2, 2, 2] Alle bereikbare sinaasappels rot
[2, 2, 0]
[0, 2, 2]
Het kernidee: multi-source BFS start vanuit meerdere knooppunten tegelijk, niet één.
Wat maakt 'Rottende Sinaasappels' anders dan standaard BFS?
Loop de matrix in spiraalvolgorde: rechts → omlaag → links → omhoog, waarbij de grenzen na elke doorgang krimpen.
def spiral(matrix):
res = []
top, bot = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1
while top <= bot and left <= right:
for c in range(left, right + 1):
res.append(matrix[top][c])
top += 1
for r in range(top, bot + 1):
res.append(matrix[r][right])
right -= 1
if top <= bot:
for c in range(right, left - 1, -1):
res.append(matrix[bot][c])
bot -= 1
if left <= right:
for r in range(bot, top - 1, -1):
res.append(matrix[r][left])
left += 1
return res
Draai een N×N-matrix met de klok mee in-place: transponeer (wissel [r][c] met [c][r]), dan keer elke rij om.
Origineel → Transponeer → Keer rijen om
1 2 3 1 4 7 7 4 1
4 5 6 → 2 5 8 → 8 5 2
7 8 9 3 6 9 9 6 3
Twee veelvoorkomende varianten:
Unieke Paden: tel paden van linksboven naar rechtsonder, alleen naar rechts of omlaag. dp[r][c] = dp[r-1][c] + dp[r][c-1].
Minimale Padsom: zelfde idee, maar kies het minimum inkomende pad.
Dit zijn vaak de zachtste introductie tot 2D dynamic programming.
In het Unieke Paden-probleem, wat is dp[0][c] voor elke kolom c?
| Patroon | Techniek | Kernprobleem | |---------|----------|--------------| | Kortste pad (ongewogen) | BFS | Doolhof kortste pad | | Verbonden componenten | DFS / BFS | Aantal Eilanden | | Multi-source verspreiding | Multi-source BFS | Rottende Sinaasappels | | Traversalvolgorde | Grenzen bijhouden | Spiraal Matrix | | In-place transformatie | Transponeer + omkeer | Afbeelding Draaien | | Paden tellen | DP | Unieke Paden | | Zoeken in gesorteerd grid | Trap / binary search | Zoek 2D Matrix |