Python 3.11+
The examples use standard Python containers and syntax available in the supported browser runtime; Matrix / Grid itself is taught as an interview abstraction.
Verify in Python docs(opens in a new tab)Two-dimensional indexed data commonly treated as rows, columns, or an implicit graph. This guide turns that contract into deliberate Python operations, interview invariants, and a runnable practice loop.
Recognize it when
Consider Matrix / Grid when the prompt's constraints and required operations match this shape: Two-dimensional indexed data commonly treated as rows, columns, or an implicit graph.

Sign in to save your code and progress across devices. The lesson and problem statement remain public.
A Python matrix is a list of row lists. Coordinates are ordered pairs (row, column), and the two
bounds are independent. A rectangular grid has a common column count; a ragged list requires a
different bound for each row and must be named as such in the contract.
Read grid[row][column]: first select a row, then a cell. For a nonempty rectangular grid, cache
rows = len(grid) and columns = len(grid[0]). Guard the empty grid before reading row zero. A
four-direction neighbor changes exactly one coordinate by one.
[[0] * columns] * rows repeats references to the same inner list. Updating one cell then changes
the corresponding column in every aliased row. A comprehension evaluates the row expression once
per iteration and creates independent row objects.
def make_grid(rows, columns, value):
return [[value for _ in range(columns)] for _ in range(rows)]Implement make_grid(rows, columns, value). Return distinct row lists so mutating one cell never changes another row.
Loading interactive editor.If it does not appear, the reference and starter code remain readable.Reload editor
The Python list documentation(opens in a new tab) defines shallow copying: copying the outer list alone does not clone nested rows.
Treat a grid as an implicit graph when movement rules define edges. Scan cells in row-major order; when an active cell is not visited, start a DFS or BFS and mark neighbors when discovered. Each cell enters one component traversal at most once, so the total work is O(rows × columns), not the number of starts multiplied by grid size.
def grid_component_sizes(grid):
if not grid:
return []
rows, columns = len(grid), len(grid[0])
visited = set()
sizes = []
for row in range(rows):
for column in range(columns):
if grid[row][column] != 1 or (row, column) in visited:
continue
stack = [(row, column)]
visited.add((row, column))
size = 0
while stack:
current_row, current_column = stack.pop()
size += 1
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
neighbor = (current_row + dr, current_column + dc)
if 0 <= neighbor[0] < rows and 0 <= neighbor[1] < columns and grid[neighbor[0]][neighbor[1]] == 1 and neighbor not in visited:
visited.add(neighbor)
stack.append(neighbor)
sizes.append(size)
return sizesImplement grid_component_sizes(grid). Return four-direction 1-component sizes in row-major discovery order without mutating the grid.
Loading interactive editor.If it does not appear, the reference and starter code remain readable.Reload editor
Use a matrix when most positions exist and direct coordinate lookup matters. Use a set or dictionary of coordinates for a huge sparse plane, especially when only a small fraction of cells are active. Use an adjacency list when neighbors are arbitrary rather than derived from local coordinate moves.
State the coordinate convention and whether diagonal movement exists. Define when a cell becomes visited and what the frontier contains. Explain O(rows × columns) by charging constant neighbor work to each cell once, and distinguish auxiliary frontier/visited space from any required output.
Visit Each Grid Component(opens in a new tab) isolates traversal mechanics. Number of Islands(opens in a new tab) requires recognizing the same implicit graph inside a larger prompt.
Python 3.11+
The examples use standard Python containers and syntax available in the supported browser runtime; Matrix / Grid itself is taught as an interview abstraction.
Verify in Python docs(opens in a new tab)Interview bounds depend on the stated representation, input model, and real Python operations.
| Operation | Average | Worst | Interview note |
|---|---|---|---|
| Core Matrix / Grid workflow | O(rows * columns) | O(rows * columns) | A grid of local neighbor connections is an implicit graph; start one traversal for each unvisited active cell. A cell is marked visited before being added to the frontier, so every active cell contributes to exactly one component. |
O(rows * columns) for the demonstrated Matrix / Grid workflow.
These are the mistakes most likely to survive a happy-path example and fail a boundary case.
Placeholder code cannot preserve the Matrix / Grid invariant or satisfy the public contract.
Prevent it: Implement the smallest complete transition and run the public tests before adding optimizations.
Avoid
def grid_component_sizes(grid):
passUse instead
def grid_component_sizes(grid):
if not grid:
return []
rows, columns = len(grid), len(grid[0])
visited = set()
sizes = []
for row in range(rows):
for column in range(columns):
if grid[row][column] != 1 or (row, column) in visited:
continue
stack = [(row, column)]
visited.add((row, column))
size = 0
while stack:
current_row, current_column = stack.pop()
size += 1
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
neighbor = (current_row + dr, current_column + dc)
if 0 <= neighbor[0] < rows and 0 <= neighbor[1] < columns and grid[neighbor[0]][neighbor[1]] == 1 and neighbor not in visited:
visited.add(neighbor)
stack.append(neighbor)
sizes.append(size)
return sizesWhere you will hit this: Visit Each Grid Component(opens in a new tab)
Treats diagonal cells as connected even though the component contract allows only four-direction neighbors.
Prevent it: Keep this invariant visible while editing: State the precise Matrix / Grid invariant before coding and preserve it after every update, traversal step, or recursive return.
Avoid
def grid_component_sizes(grid):
if not grid: return []
rows, columns = len(grid), len(grid[0])
visited = set(); sizes = []
for row in range(rows):
for column in range(columns):
if grid[row][column] != 1 or (row, column) in visited: continue
stack = [(row, column)]; visited.add((row, column)); size = 0
while stack:
r, c = stack.pop(); size += 1
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (-1, -1)):
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < columns and grid[nr][nc] == 1 and (nr, nc) not in visited:
visited.add((nr, nc)); stack.append((nr, nc))
sizes.append(size)
return sizesUse instead
def grid_component_sizes(grid):
if not grid:
return []
rows, columns = len(grid), len(grid[0])
visited = set()
sizes = []
for row in range(rows):
for column in range(columns):
if grid[row][column] != 1 or (row, column) in visited:
continue
stack = [(row, column)]
visited.add((row, column))
size = 0
while stack:
current_row, current_column = stack.pop()
size += 1
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
neighbor = (current_row + dr, current_column + dc)
if 0 <= neighbor[0] < rows and 0 <= neighbor[1] < columns and grid[neighbor[0]][neighbor[1]] == 1 and neighbor not in visited:
visited.add(neighbor)
stack.append(neighbor)
sizes.append(size)
return sizesWhere you will hit this: Visit Each Grid Component(opens in a new tab)
Handle empty state, duplicate values, aliasing, and serialization boundaries explicitly in tests.
Prevent it: Account for every slice, copy, sort, membership test, and container mutation before claiming O(rows * columns).
Avoid
def grid_component_sizes(grid):
if not grid: return []
rows, columns = len(grid), len(grid[0])
visited = set(); sizes = []
for row in range(rows):
for column in range(columns):
if grid[row][column] != 1 or (row, column) in visited: continue
stack = [(row, column)]; visited.add((row, column)); size = 0
while stack:
r, c = stack.pop(); size += 1
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (-1, -1)):
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < columns and grid[nr][nc] == 1 and (nr, nc) not in visited:
visited.add((nr, nc)); stack.append((nr, nc))
sizes.append(size)
return sizesUse instead
def grid_component_sizes(grid):
if not grid:
return []
rows, columns = len(grid), len(grid[0])
visited = set()
sizes = []
for row in range(rows):
for column in range(columns):
if grid[row][column] != 1 or (row, column) in visited:
continue
stack = [(row, column)]
visited.add((row, column))
size = 0
while stack:
current_row, current_column = stack.pop()
size += 1
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
neighbor = (current_row + dr, current_column + dc)
if 0 <= neighbor[0] < rows and 0 <= neighbor[1] < columns and grid[neighbor[0]][neighbor[1]] == 1 and neighbor not in visited:
visited.add(neighbor)
stack.append(neighbor)
sizes.append(size)
return sizesWhere you will hit this: Number of Islands(opens in a new tab)
Official Python documentation supports language behavior. Canonical problem pages provide additional practice context.
python-docs · checked 2026-07-27