Unique Paths
Only one row of counts is needed. Row r is built from row r − 1 and the cell to its left. Going left to right, row[c] += row[c − 1] turns the old row into the new one. Before that line runs, row[c] still holds the cell above, and row[c − 1] already holds the cell to the left.
After row r is done, row[c] is the number of paths to cell (r, c), because the update adds exactly the cell above and the cell to the left.
Problem
A robot stands in the top-left corner of a grid with m rows and n columns. It wants to reach the bottom-right corner. Each move takes it one cell down or one cell right. It never moves up or left.
Return how many different paths it can take.
Two whole numbers: m, the number of rows, and n, the number of columns.
The number of different paths from the top-left cell to the bottom-right cell.
A path has 2 downs and 6 rights, in some order. Choose which 2 of the 8 moves are down: C(8, 2) = 28.
The three paths are Right → Down → Down, Down → Down → Right and Down → Right → Down.
- • 1 ≤ m, n ≤ 100
- • The tests are chosen so that the answer is at most 2 × 10^9.
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.
- 1.
Every path has the same number of moves. How many moves is that, in terms of m and n?
- 2.
The robot never moves up or left. What does that say about how many downs and rights every path has?
- 3.
To reach a cell that is not in the top row or the left column, what was the last move?
- 4.
If I know how many paths reach the cell above and the cell to its left, how do I count the paths to this cell?
- 5.
Would the length of the shortest route to the corner tell me how many routes there are? Why or why not?
Brute force approach
Better approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | Count the paths into a cell by adding the counts of the two cells that can feed it | O(2^(M + N)) | O(M + N) |
| Better | dp[r][c] = dp[r−1][c] + dp[r][c−1], with every cell worked out once and stored | O(M · N) | O(M · N) |
| Optimal | Keep one row of counts; for each cell, row[c] += row[c − 1] | O(M · N) | O(N) |
Why does this belong to this pattern?
- “move only down or right”A cell can only be entered from above or from the left. The last move decides which counts to add.
- “how many different paths”The goal is a count, not a shortest distance. Add the counts of the cells that feed each cell.
- “from the top-left to the bottom-right”The answer for the corner is built from the answers for the cells before it, so fill the table in order.
This is the anchor of the Paths sub-pattern. Every cell's count is the sum of the two cells that can feed it, and the top row and the left column start at 1. No cell is blocked here, so there is no validity rule at all. The next questions change one rule each: an obstacle forces a count to 0, a cost turns the sum into a minimum, and more feeding cells change the list of neighbours.
Don't make this mistake
Every path to the bottom-right corner has the same length, m + n − 2 moves, so a BFS only finds that length. On a 3 × 3 board the BFS reaches the corner after 4 moves, but there are 6 paths. A length does not tell you how many routes there are.
Walking every path (DFS or plain recursion) counts the paths one by one. On a 10 × 10 board the plain recursion makes 97,239 calls for 100 cells. The number of paths grows much faster than the number of cells, so the table, which does M · N steps, is the only version that scales.
A 0 on the edge stops the sums: every cell is built from edge cells, so every cell becomes 0. For 3 × 7 the table is all 0s, and the answer is 0 instead of 28.
Rows are numbered 0 to m − 1 and columns 0 to n − 1, so index m (or n) is one past the end of the table. The answer is the bottom-right cell.
Want to implement this?
Write it yourself on LeetCode, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like DP — Grid translate into production architectures and low-level memory mechanics.
Foundations: Object-Oriented Principles in C++23
Class invariants, pure virtual interfaces, and RAII smart pointers.
Food Delivery System (Zomato Architecture)
Real-world machine coding application of algorithms and design patterns.
Pointers vs References Deep Dive
Pointer arithmetic and memory layout under the hood.
Virtual Method Table (vtable) & Memory Layout
Polymorphism, vptr overhead, and multiple inheritance in memory.