Unique Paths II
The drill: Same right/down grid walk as before, but some cells are boulders that block the route entirely. Count the paths from the top-left corner to the bottom-right that never step on one.
The same right/down grid walk returns, except now some cells are marked as obstacles that block the route entirely — a route can never step onto one of those cells.
The runner still starts in the top-left corner and must reach the bottom-right corner using only right and down moves, and the count needed is how many distinct obstacle-free routes exist between those two corners.
If the starting cell or the ending cell itself is blocked, no route can exist at all, and the answer collapses to zero.
- the grid marks obstacles distinctly from open cells
- the start or end cell can itself be an obstacle, giving zero routes
- movement is limited to a single step right or a single step down
- grid sizes stay small enough for an O(m·n) table
HINT 1 THE NUDGE
The recursion is identical to the open grid — except a blocked cell contributes zero routes instead of one. Where does that zero need to propagate?
HINT 2 THE STRUCTURE
A blocked cell has no ways to be reached and nothing to pass forward — both directions collapse to zero, including if the blocker sits on the starting cell itself.
HINT 3 ONE STEP FROM THE ANSWER
Reuse the rolling-row DP: ways[c] += ways[c-1] normally, but slam ways[c] to 0 the instant an obstacle occupies that cell, before it can contribute to its neighbour.
Seed the entrance with one way to stand there, doing nothing.
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
m, n = len(obstacleGrid), len(obstacleGrid[0])
row = [0] * n
row[0] = 1
for r in range(m):
for c in range(n):
if obstacleGrid[r][c] == 1:
row[c] = 0
elif c > 0:
row[c] += row[c - 1]
return row[-1]class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
m, n = len(obstacleGrid), len(obstacleGrid[0])
def paths(r, c):
if obstacleGrid[r][c] == 1:
return 0
if r == m - 1 and c == n - 1:
return 1
total = 0
if r + 1 < m:
total += paths(r + 1, c)
if c + 1 < n:
total += paths(r, c + 1)
return total
return paths(0, 0)class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length, n = obstacleGrid[0].length;
int[] row = new int[n];
row[0] = 1;
for (int r = 0; r < m; r++) {
for (int c = 0; c < n; c++) {
if (obstacleGrid[r][c] == 1) {
row[c] = 0;
} else if (c > 0) {
row[c] += row[c - 1];
}
}
}
return row[n - 1];
}
}class Solution {
private int[][] grid;
private int m, n;
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
grid = obstacleGrid;
m = grid.length;
n = grid[0].length;
return paths(0, 0);
}
private int paths(int r, int c) {
if (grid[r][c] == 1) {
return 0;
}
if (r == m - 1 && c == n - 1) {
return 1;
}
int total = 0;
if (r + 1 < m) {
total += paths(r + 1, c);
}
if (c + 1 < n) {
total += paths(r, c + 1);
}
return total;
}
}✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED