Count paths from the top-left to bottom-right when moves can only go right or down.
Start with the concrete trace below. It shows the state the algorithm must carry as it runs.
Problem trace
Unique Paths: Sweep a 3 by 3 grid row by row; each interior count is old ways[col] from above plus new ways[col-1] from the left.
Input and goalCount paths from the top-left to bottom-right when moves can only go right or down.
Initialize the first rowFor a 3 by 3 grid, ways = [1,1,1] because each top-row cell has exactly one all-right path from the start.
1start/current11??????
rollingRow[1,1,1]
Update row 1, column 1The old ways[1] = 1 is from above and new ways[0] = 1 is from the left, so ways[1] becomes 1 + 1 = 2.
11above11left2current????
recurrenceabove 1 + left 1 = 2rollingRow[1,2,1]
Update row 1, column 2The old ways[2] = 1 is from above and ways[1] = 2 is from the left, so ways[2] becomes 1 + 2 = 3.
111above12left3current???
recurrenceabove 1 + left 2 = 3rollingRow[1,2,3]
Update row 2, column 1The old ways[1] = 2 is from above and the first-column value is 1, so ways[1] becomes 2 + 1 = 3.
11112above31left3current?
recurrenceabove 2 + left 1 = 3rollingRow[1,3,3]
Reach the destinationAt row 2, column 2, old ways[2] = 3 comes from above and new ways[1] = 3 from the left, so 3 + 3 = 6.
111123above13left6current
recurrenceabove 3 + left 3 = 6rollingRow[1,3,6]result6
Recognize it
Use it when movement forms an acyclic grid and every path into a cell must arrive through a small fixed set of predecessor directions such as above and left.
Keep true
During a row sweep, ways[col] before update is the count from above and ways[col-1] after update is the count from the left; their sum is the current cell count.
Reuse it
When dependencies come from the previous row and current row prefix, sweep in the direction that preserves both and compress the grid to one mutable row.
Read it this way: For a 3 by 3 grid, ways = [1,1,1] because each top-row cell has exactly one all-right path from the start. Step through the frames to watch the state change. The last frame shows the answer or the stopping condition.
Pattern: Grid DP stored as one row.
Simple idea: Every cell can be reached from above or from the left. The old value in the
array is the count from above. The new value to its left is the count from the left.
def unique_paths(rows: int, cols: int) -> int: ways = [1] * cols for _ in range(1, rows): for col in range(1, cols): ways[col] += ways[col - 1] return ways[-1]