Unique Paths in Grid DP in DSA C++ - Time & Space Complexity
We want to understand how the time needed to find unique paths in a grid grows as the grid size increases.
How does the number of steps change when the grid gets bigger?
Analyze the time complexity of the following code snippet.
int uniquePaths(int m, int n) {
vector<vector<int>> dp(m, vector<int>(n, 1));
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
This code calculates the number of unique paths from the top-left to the bottom-right of an m by n grid using dynamic programming.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops filling the dp table.
- How many times: The inner addition runs for each cell except the first row and column, roughly (m-1) * (n-1) times.
As the grid size grows, the number of operations grows roughly with the total number of cells.
| Input Size (m x n) | Approx. Operations |
|---|---|
| 10 x 10 | 81 |
| 100 x 100 | 9,801 |
| 1000 x 1000 | 998,001 |
Pattern observation: Operations grow roughly by the product of m and n, so doubling both roughly quadruples the work.
Time Complexity: O(m * n)
This means the time needed grows proportionally to the number of cells in the grid.
[X] Wrong: "Since there are many paths, the time must be exponential."
[OK] Correct: The dynamic programming approach avoids recalculating paths by storing results, so it only visits each cell once.
Understanding this time complexity shows you can analyze how dynamic programming improves efficiency by reducing repeated work.
"What if we used recursion without memoization? How would the time complexity change?"
Practice
Given a grid of size m x n, how many unique paths exist from the top-left corner to the bottom-right corner if you can only move right or down?Solution
Step 1: Understand the problem statement
The problem asks for counting all possible unique paths from the top-left to bottom-right corner of a grid, moving only right or down.Step 2: Clarify what is being counted
We count the number of ways to reach the destination, not the shortest path or sums.Final Answer:
The number of different ways to reach the bottom-right corner moving only right or down -> Option AQuick Check:
Unique paths count = number of ways [OK]
- Confusing path count with shortest path length
- Thinking about obstacles when none are given
- Mixing sum of values with path count
dp of size m x n with all values 0 in C++?Solution
Step 1: Understand 2D vector initialization syntax
In C++, a 2D vector is initialized by specifying rows and columns with default values.Step 2: Check each option
std::vector dp(m, std::vector<int>(n, 0)); correctly creates a vector with m rows and n columns, all initialized to 0.Final Answer:
std::vector dp(m, std::vector<int>(n, 0)); -> Option CQuick Check:
Correct 2D vector init syntax = std::vector dp(m, std::vector<int>(n, 0)); [OK]
- Swapping m and n in initialization
- Using wrong vector constructor parameters
- Missing default value initialization
int m = 3, n = 3;
std::vector dp(m, std::vector<int>(n, 0));
for (int i = 0; i < m; i++) dp[i][0] = 1;
for (int j = 0; j < n; j++) dp[0][j] = 1;
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
std::cout << dp[m-1][n-1] << std::endl;Solution
Step 1: Initialize first row and column
First row and column are set to 1, representing only one path to each cell along edges.Step 2: Fill dp table using dp[i][j] = dp[i-1][j] + dp[i][j-1]
Calculate dp values for inner cells:
dp[1][1] = 1+1=2
dp[1][2] = 1+2=3
dp[2][1] = 2+1=3
dp[2][2] = 3+3=6Final Answer:
6 -> Option DQuick Check:
Unique paths in 3x3 grid = 6 [OK]
- Not initializing first row and column to 1
- Using wrong indices in dp update
- Confusing addition with multiplication
int uniquePaths(int m, int n) {
std::vector dp(m, std::vector<int>(n));
for (int i = 0; i < m; i++) dp[i][0] = 1;
for (int j = 0; j < n; j++) dp[0][j] = 1;
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i-1][j] * dp[i][j-1];
}
}
return dp[m-1][n-1];
}Solution
Step 1: Check dp update formula
The code uses multiplication: dp[i][j] = dp[i-1][j] * dp[i][j-1], which is incorrect for counting paths.Step 2: Correct formula for unique paths
The correct formula adds the number of ways from top and left cells: dp[i][j] = dp[i-1][j] + dp[i][j-1].Final Answer:
The multiplication operator should be addition in dp update -> Option AQuick Check:
Use addition, not multiplication for path counts [OK]
- Using multiplication instead of addition in dp formula
- Returning wrong dp cell
- Not initializing first row or column
Consider the grid:
0 0 0 0 1 0 0 0 0
Solution
Step 1: Handle obstacles in dp initialization
If a cell has an obstacle (value 1), set dp[i][j] = 0 because no path can go through it.Step 2: Update dp values considering obstacles
For other cells, dp[i][j] = dp[i-1][j] + dp[i][j-1], summing paths from top and left only if those cells are reachable.Final Answer:
Set dp[i][j] = 0 if grid[i][j] is 1, else dp[i][j] = dp[i-1][j] + dp[i][j-1] -> Option BQuick Check:
Obstacles block paths, set dp to 0 there [OK]
- Ignoring obstacles in dp calculation
- Using multiplication instead of addition
- Setting dp to 1 for obstacle cells
Ready to prove it?
Pass the test and this pattern moves unknown
