Debugging challengeBeginner
The grid whose rows moved together
Scenario
An island counter builds a visited grid with [[False] * cols] * rows and runs a standard DFS flood fill. On the sample grid it reports 2 islands instead of 3. Stranger: printing visited after marking a single cell shows the mark appearing in *every row at once*. The DFS itself is correct. Find the bug.
1def num_islands(grid):2 rows, cols = len(grid), len(grid[0])3 visited = [[False] * cols] * rows # rows * rows... or is it?4 5 def dfs(r, c):6 if r < 0 or c < 0 or r >= rows or c >= cols:7 return8 if visited[r][c] or grid[r][c] == 0:9 return10 visited[r][c] = True11 dfs(r + 1, c)12 dfs(r - 1, c)13 dfs(r, c + 1)14 dfs(r, c - 1)15 16 count = 017 for r in range(rows):18 for c in range(cols):19 if grid[r][c] == 1 and not visited[r][c]:20 count += 121 dfs(r, c)22 return count23 24 25demo = [[False] * 3] * 226demo[0][0] = True27print(demo) # [[True, False, False], [True, False, False]]28print(demo[0] is demo[1]) # True — both rows are the same list29 30grid = [[1, 0, 1],31 [1, 0, 0],32 [0, 0, 1]]33print(num_islands(grid)) # 2, expected 3Your task
- What does
list * ndo with the elements — copy them, or something else? Why doesdemo[0] is demo[1]printTrue? - Why is the *inner*
[False] * colsnot a problem, while the outer* rowsis? - Trace the island count on the sample grid and show which island is lost.
- Write the correct grid construction. Why does a list comprehension fix it?
- Name two other places the same aliasing bite appears (shallow copies,
dict.fromkeys,copyvsdeepcopy). - State the complexity of the fixed algorithm.
DebuggingSystematic ReasoningImplementation
Work it out
Write your analysis before revealing anything. The self-check below compares it against what a strong answer contains.
Reveal
Progressive — each section builds on the previous one.
The bug
Why it happens
The fix
Edge cases
Complexity
Self-check
Tick what your analysis covered. Be honest — this feeds your readiness profile.