intermediate8 min read·Updated October 6, 2026

Unique Paths with Obstacles Explained: Tracing the 3x3 Grid

Master unique paths with obstacles using dynamic programming. Follow a complete step-by-step trace of a 3x3 grid with a center block. Clear mental model included.

By Learnisim AI·Published October 6, 2026
LEARNING ARCSetup → Model in the example → Full trace → Twist → Edge cases → Apply
PREREQUISITES
  • Basic 2D arrays
  • Introduction to Dynamic Programming
  • Grid traversal fundamentals
Unique Paths with Obstacles: DP on [[0,0,0],[0,1,0],[0,0,0]] 3×3 DP Result Table (0,0) 1 (0,1) 1 (0,2) 1 (1,0) 1 Boulder 0 (1,2) 1 (2,0) 1 (2,1) 1 Goal 2 0 = Free path | 1 = Obstacle (DP = 0) Total Unique Paths = 2 Allowed moves: Right (→) & Down (↓) State Transition Rule DP[i][j] = DP[i-1][j] + DP[i][j-1] Sum of paths from Above + Left If Grid[i][j] == 1 (Obstacle): DP[i][j] = 0 (Quarantines Dead End) No routes can pass through solid rock Answering the Key Question: Why does DP[2][1] = 1? The Formula at (2,1): DP[2][1] = DP[1][1] + DP[2][0] Incoming from Above + Left Substitution Check: DP[2][1] = 0 (above) + 1 (left) Result = 1 valid path arriving here Key Takeaway: Obstacles block paths from passing THROUGH them, but free cells below/right can still receive paths from open neighbors!
Paths on [[0,0,0],[0,1,0],[0,0,0]] overview diagram
Why

Why Counting Unique Paths with Obstacles is Tricky

Phase 1: The Maze with a Pebble in the Center

Imagine you are standing at the top-left corner of a 3x3 grid, looking down at the bottom-right destination. Without any obstacles, counting paths using combinatorics or straightforward addition is easy. But what happens when someone places a concrete boulder right in the middle? For our locked working example, let us define the grid as:
[[0, 0, 0],
[0, 1, 0],
[0, 0, 0]]
Here, 0 represents open terrain and 1 represents an impassable obstacle at coordinate —the exact center. You are only allowed to move right or down.
If you blindly apply a naive formula that assumes an open grid, your calculation will happily route right through the boulder as if it were empty space. In reality, that boulder abruptly severs certain corridors, forcing traffic to bend outward. We need a systematic way to account for these obstacles without manually tracing every single pencil line on a napkin.
python
grid = [
    [0, 0, 0],
    [0, 1, 0],
    [0, 0, 0]
]
Counting Unique Paths with Obstacles: [[0,0,0], [0,1,0], [0,0,0]] Dynamic Programming Grid (DP) 1 (0,0) Start 1 (0,1) 1 (0,2) 1 (1,0) BOULDER val = 0 1 (1,2) 1 (2,0) 2 (2,1) = 1+1 2 Goal: 2 Paths Move right or down only. Obstacle cuts off paths! 1. The Naive Formula Trap Naive combinatorics like C(4,2) assume open space. Result = 6 paths. But the center boulder blocks routes! Actual valid paths: exactly 2 paths circumventing it. 2. DP Recurrence Relation If grid[i][j] == 1: dp[i][j] = 0 (Dead zone) Else: dp[i][j] = dp[i-1][j] + dp[i][j-1] Accumulates valid traffic arriving from top & left. 3. Why Counting with Obstacles is Tricky • Zeroes propagate and abruptly sever corridors. • Forces traffic to bend outward around obstacles. Essential pattern for robot navigation & grid puzzles.
Why Counting Unique Paths with Obstacles is Tricky diagram
Model

Building the Grid Model: States, Transitions, and Walls

Phase 2: Mapping Grid Cells to State Transitions

To count every valid journey from the top-left corner to the bottom-right corner of our 3×3 grid [[0,0,0],[0,1,0],[0,0,0]], we need a mathematical model that breaks the grand journey down into local choices. At any free cell , you could have arrived from the cell directly above it or the cell directly to its left . Because our rules restrict movement strictly to right and down, there are no diagonal arrivals or backtracking loops.
This structural constraint turns a messy global routing puzzle into a clean recurrence relation. Let represent the total number of unique paths to reach cell from our starting position at . If the current cell contains an obstacle (a value of 1), it acts as a permanent dead end, meaning because zero paths can pass through solid rock. If the cell is free (a value of 0), the total paths to get here is simply the sum of the paths coming from above plus the paths coming from the left:
.
Let us apply this logic to our working example's center cell at , which contains an obstacle (1). Even if paths could somehow flow into it, setting instantly quarantines the hazard, preventing any subsequent rightward or downward step from inheriting those dead routes. The outer boundaries also form natural walls: any cell in the first row can only be reached by moving continuously right, unless an obstacle blocks the corridor ahead.
Building the Grid Model: States, Transitions, and Walls DP[i][j] = DP[i-1][j] + DP[i][j-1] (Obstacle at [1,1] sets DP=0) 3×3 Grid Working Example [0,0] Start DP = 1 [0,1] DP = 1 [0,2] DP = 1 [1,0] DP = 1 [1,1] Wall DP = 0 [1,2] DP = 2 [2,0] DP = 1 [2,1] DP = 3 [2,2] Goal DP = 5 Values show total unique paths from top-left to each cell State Transition & Wall Quarantine Local Choice Recurrence DP[i][j] = DP[i-1][j] + DP[i][j-1] Arrival strictly from Above or Left (Right & Down moves only) Permanent Obstacle Quarantine If Grid[i][j] == 1 ⇒ DP[i][j] = 0 Dead end isolates hazard; paths cannot pass through solid rock Prevents subsequent right/down steps from inheriting dead routes Grand Journey Resolution Target DP[2][2] = DP[1][2] + DP[2][1] DP[2][2] = 2 + 3 = 5 Unique Paths Transforms global routing puzzle into clean local additions
Building the Grid Model: States, Transitions, and Walls diagram
Worked example

Tracing Dynamic Programming on the 3x3 Blocked Grid

Phase 3: Walking the Table

To see our dynamic programming model in action, we compute the path counts cell by cell for our grid:

Given

- Start cell at with an initial path count of dp[0][0] = 1.
- The center obstacle at has value 1, making dp[1][1] = 0.
•Allowed moves: right and down only.

Steps

1.Initialize the top row and left column:

- dp[0][0] = 1
- dp[0][1] = dp[0][0] + 0 = 1 (moving right)
- dp[0][2] = dp[0][1] + 0 = 1 (moving right)
- dp[1][0] = dp[0][0] + 0 = 1 (moving down)
- dp[2][0] = dp[1][0] + 0 = 1 (moving down)
2.Fill the interior cells (Row 1):

- For , the cell is blocked (grid[1][1] == 1), so dp[1][1] = 0.
- For , dp[1][2] = dp[0][2] + dp[1][1] = 1 + 0 = 1.
3.Fill the interior cells (Row 2):

- For , dp[2][1] = dp[1][1] + dp[2][0] = 0 + 1 = 1.
- For (the destination), dp[2][2] = dp[1][2] + dp[2][1] = 1 + 1 = 2.

Result

The complete DP table is:
[[1, 1, 1],
[1, 0, 1],
[1, 1, 2]]
The total number of unique paths to the bottom-right corner is 2.
Try this: Given the intermediate table row dp[1] = [1, 0, 1], explain why dp[2][1] receives a value of 1 instead of 0 despite dp[1][1] being an obstacle.
Phase 3: Walking the DP Table (3x3 Grid) dp[2][1] = dp[1][1] (0) + dp[2][0] (1) = 1 Dynamic Programming Table (0,0) 1 (0,1) 1 (0,2) 1 (1,0) 1 Obstacle 0 (1,2) 1 (2,0) 1 Target 1 Dest 2 Focus: Calculating dp[2][1] dp[2][1] = dp[1][1] + dp[2][0] Sum paths from Top and Left neighbors ! Top: dp[1][1] (Obstacle) Value = 0 (no paths through wall) ← Left: dp[2][0] (Valid) Value = 1 (paths arrive from above) Result: 0 + 1 = 1 unique path
Tracing Dynamic Programming on the 3x3 Blocked Grid diagram
Practice

Predicting Path Count Changes with a New Obstacle

Phase 4: Practice

In our previous trace on the grid [[0,0,0],[0,1,0],[0,0,0]], the single obstacle at grid[1][1] forced the center cell's path count to 0 and left us with exactly 2 valid paths. But what happens if we shift the hazard just one step to the right into the bottom-right quadrant? Let us test your mental model of state transitions and zeroed-out paths before looking at the final deduction.
Consider a modified grid where the obstacle moves from the center grid[1][1] to grid[1][2], making our input [[0,0,0],[0,0,1],[0,0,0]].

The Challenge

Trace through the dynamic programming table row by row for this new grid. Keep in mind that any cell with an obstacle (1) immediately receives 0 paths, and any cell whose top and left ancestors are both blocked or zeroed will also cascade to 0.
- What is the path count at dp[1][2] (the obstacle cell)?
- What is the final path count at dp[2][2] (the bottom-right destination)?
python
# Modified 3x3 grid with obstacle shifted to grid[1][2]
grid = [
    [0, 0, 0],
    [0, 0, 1],
    [0, 0, 0]
]

# Question: How many unique paths exist from (0,0) to (2,2)?
# Write down or mentally trace the dp table values for row 1 and row 2.
Apply

Transferring Grid Routing Logic to Larger Maps and Constraints

Phase 5: Applying the DP Model Beyond the 3x3 Grid

Now that you have traced the 3x3 grid with its center hazard at [1][1] yielding exactly 2 unique paths, let us transfer this exact dynamic programming mental model to a larger or differently constrained environment.
Recall the fundamental recurrence relation that governed our work:
When scaling this logic to an grid, the size of the board changes, but the local constraint propagation remains identical. Every cell is still strictly a function of its immediate northern and western precursors. If you encounter a labyrinth where obstacles form continuous walls (such as a vertical barrier splitting the grid in half), the accumulation of paths halts entirely along that boundary, starving any destination downstream.
To apply this effectively in code or design, always ensure your boundary conditions (the first row and first column) properly stop propagating paths the moment a single 1 appears. From there, the two-dimensional state transition handles the rest, whether the grid is , , or irregular in shape.
python
def uniquePathsWithObstacles(grid: list[list[int]]) -> int:
    # Apply your transfer knowledge here
    pass

FAQ

How many unique paths exist in the 3x3 grid with an obstacle at the center?
There are exactly 2 unique paths. Moving only right or down, you must navigate around the center obstacle at coordinates (1,1) by taking either the top-right or bottom-left perimeter.
How do obstacles affect the dynamic programming state transition?
If a cell contains an obstacle (represented by 1), its path count is set to 0 because no paths can flow through it. Additionally, any incoming paths from the top or left cannot pass through that blocked cell.
What is the time and space complexity of solving grid path problems with DP?
The time complexity is O(M × N) where M and N are the grid dimensions, as we visit every cell once. Space complexity is O(M × N) for the DP table, which can be optimized to O(N) using a single-row rolling array.
What happens if the start or end cell itself contains an obstacle?
If the start cell (0,0) or the destination cell contains an obstacle, the total number of unique paths is immediately 0, since you cannot start or successfully reach the destination.

Keep learning