Unique Paths II

MediumDynamic Programming · 2D Grid🧩 Grid DPLeetCode #63 ↗Updated

Problem

A robot starts at the top-left cell of an m × n grid and wants to reach the bottom-right cell, moving only right or down. Cells marked 1 are obstacles that cannot be entered. Count the distinct paths (0 if the start or end is blocked).
Input[[0,0,0],[0,1,0],[0,0,0]]Output2
Input[[0,1],[0,0]]Output1
Input[[1]]Output0

1 ≤ m, n ≤ 100  ·  grid[i][j] ∈ {0, 1}  ·  answer ≤ 2·109

Try it yourself

Java
class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Paths into a free cell = paths into the cell above + paths into the cell to the left; an obstacle cell has 0 paths. Filling row by row, one array of width n is enough.
PatternGrid DP

Instinct Grid moves that never loop back (right/down, row to row) plus "count or optimise the paths" - build dp[r][c] from the cells that can step in.

Memory hack Every cell asks its parents - a cell's answer comes only from the neighbours that can move into it, so fill cells in the order they arrive.

Open the Grid DP guide →

Approaches

Brute ForceRecursion (Try Right & Down)

Time O(2m+n)Space O(m + n)

From (row, col) the number of paths to the goal is the sum of paths after stepping right and after stepping down. Leaving the grid or hitting an obstacle contributes 0; reaching the goal contributes 1.

Java
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
    return countPaths(0, 0, obstacleGrid);
}
private int countPaths(int row, int col, int[][] grid) {
    if (row >= grid.length || col >= grid[0].length || grid[row][col] == 1)
        return 0;                                   // off-grid or blocked
    if (row == grid.length - 1 && col == grid[0].length - 1) return 1;
    return countPaths(row, col + 1, grid) + countPaths(row + 1, col, grid);
}

Direct translation of the rules, but the same cells are re-solved exponentially often.

At a glance

LevelApproachTimeSpace
Brute ForceRecursion (Try Right & Down)O(2m+n)O(m + n)
BetterTop-Down MemoizationO(m · n)O(m · n)
OptimalBottom-Up 1D DP (Rolling Row)O(m · n)O(n)
Common pitfalls
  • Initialising the first row/column to all 1s — cells past an obstacle are unreachable.
  • Ignoring a blocked start or end cell — the answer must be 0.
  • Forgetting to zero dp[j] on an obstacle — stale value from the row above leaks.
Interview tips
  • Start from Unique Paths (62) and add one rule: obstacle → 0.
  • Show recursion → memo → table → 1D as a natural progression.
  • Point out the recursion depth is only m + n, but the tree is exponential.
Pattern
2D grid path DP → count/optimise paths with right/down moves; state = cell, combine top & left.
My notes saved in this browser