Une matrice est simplement un tableau 2D, mais en entretien elle représente souvent une grille - une carte, un plateau ou un labyrinthe. Chaque cellule grid[r][c] est un nœud, et ses voisins sont les cellules adjacentes.
grid = [
[1, 1, 0],
[1, 0, 0],
[0, 0, 1]
]
Ligne r, colonne c, dimensions m × n. Simple - mais les patrons construits dessus sont puissants.
Au lieu d'écrire quatre instructions if séparées, utilisez un tableau de directions :
# 4-directional (up, down, left, right)
dirs = [(-1,0), (1,0), (0,-1), (0,1)]
# 8-directional (includes diagonals)
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:
# process neighbour
C'est l'extrait de code le plus réutilisable dans les problèmes de grilles.
Le BFS trouve le plus court chemin dans une grille non pondérée. On part de la source, on explore tous les voisins à distance 1, puis à distance 2, et ainsi de suite.
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
Sign in to join the discussion
Flood fill (comme l'outil pot de peinture) : depuis une cellule de départ, changer toutes les cellules connectées de même couleur. DFS ou BFS fonctionnent.
Nombre d'îles : parcourir la grille ; quand on trouve un 1, lancer un DFS/BFS pour marquer l'île entière comme visitée, puis incrémenter le compteur.
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) # mark island
count += 1
return count
Dans « Nombre d'îles », pourquoi marque-t-on les cellules comme visitées pendant le DFS ?
Toutes les oranges initialement pourries sont des sources. On les insère toutes dans la file au temps 0, puis BFS. Chaque niveau = une minute. L'idée clé : le BFS multi-source démarre depuis plusieurs nœuds simultanément.
Minute 0: [2, 1, 1] Minute 4: [2, 2, 2]
[1, 1, 0] [2, 2, 0]
[0, 1, 1] [0, 2, 2]
Qu'est-ce qui différencie « Oranges pourries » d'un BFS standard ?
Parcourir la matrice en spirale : droite → bas → gauche → haut, en réduisant les limites après chaque passage.
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
Rotation horaire N×N sur place : transposer puis inverser chaque ligne.
Original → Transpose → Reverse rows
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
Chemins uniques : compter les chemins du coin supérieur gauche au coin inférieur droit en ne se déplaçant que vers la droite ou le bas. dp[r][c] = dp[r-1][c] + dp[r][c-1].
Somme de chemin minimale : même idée mais en prenant le chemin entrant minimal.
Dans le problème Chemins uniques, que vaut dp[0][c] pour toute colonne c ?
| Patron | Technique | Problème clé | |--------|-----------|--------------| | Plus court chemin (non pondéré) | BFS | Plus court chemin dans un labyrinthe | | Composantes connexes | DFS / BFS | Nombre d'îles | | Propagation multi-source | BFS multi-source | Oranges pourries | | Ordre de parcours | Pointeurs de limites | Matrice en spirale | | Transformation sur place | Transposer + inverser | Rotation d'image | | Comptage de chemins | DP | Chemins uniques | | Recherche dans grille triée | Escalier / binary search | Search 2D Matrix |