Minimum Path Sum in Grid in DSA C++ - Time & Space Complexity
We want to know how the time needed to find the minimum path sum in a grid changes as the grid size grows.
How does the number of steps grow when the grid gets bigger?
Analyze the time complexity of the following code snippet.
int minPathSum(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
vector<vector<int>> dp(m, vector<int>(n));
dp[0][0] = grid[0][0];
for (int i = 1; i < m; i++)
dp[i][0] = dp[i-1][0] + grid[i][0];
for (int j = 1; j < n; j++)
dp[0][j] = dp[0][j-1] + grid[0][j];
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j];
}
}
return dp[m-1][n-1];
}
This code finds the smallest sum of numbers on a path from the top-left to the bottom-right of a grid, moving only down or right.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops filling the dp table for each cell.
- How many times: The inner loop runs for each cell except the first row and column, so roughly m x n times.
As the grid size grows, the number of cells to process grows with the product of rows and columns.
| Input Size (m x n) | Approx. Operations |
|---|---|
| 10 x 10 | 100 |
| 100 x 100 | 10,000 |
| 1000 x 1000 | 1,000,000 |
Pattern observation: The operations grow roughly by the square of the grid size, meaning doubling rows and columns quadruples work.
Time Complexity: O(m x n)
This means the time needed grows proportionally to the total number of cells in the grid.
[X] Wrong: "Since we only move right or down, the path count is exponential, so the time is exponential too."
[OK] Correct: The code uses dynamic programming to store results for each cell once, avoiding repeated work and keeping time linear in the number of cells.
Understanding this time complexity shows you can analyze grid-based dynamic programming efficiently, a common skill in coding challenges and interviews.
"What if we allowed moving diagonally as well? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem goal
The problem asks for the minimum sum of values collected when moving from the top-left corner to the bottom-right corner of a grid, moving only right or down.Step 2: Clarify movement constraints
Only moves to the right or down are allowed, so the path is restricted and the sum depends on chosen cells.Final Answer:
The smallest sum of numbers along a path from top-left to bottom-right, moving only right or down. -> Option DQuick Check:
Minimum path sum = smallest sum path [OK]
- Thinking diagonal moves are allowed
- Looking for maximum sum instead of minimum
- Counting number of paths instead of sum
grid with 3 rows and 4 columns filled with zeros?Solution
Step 1: Understand 2D vector initialization syntax
To create a 2D vector with 3 rows and 4 columns filled with zeros, we use vector of vectors: outer vector size 3, inner vector size 4, each element 0.Step 2: Check each option
std::vector grid(3, std::vector<int>(4, 0)); correctly uses std::vector grid(3, std::vector<int>(4, 0)); which means 3 rows, each row is a vector of 4 zeros.Final Answer:
std::vector grid(3, std::vector<int>(4, 0)); -> Option AQuick Check:
Correct 2D vector init = std::vector grid(3, std::vector<int>(4, 0)); [OK]
- Using wrong vector type for 2D
- Swapping rows and columns sizes
- Trying to pass three arguments to vector constructor
std::vector grid = {{1, 3}, {1, 5}};
int m = grid.size();
int n = grid[0].size();
for (int i = 1; i < m; i++) grid[i][0] += grid[i-1][0];
for (int j = 1; j < n; j++) grid[0][j] += grid[0][j-1];
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
grid[i][j] += std::min(grid[i-1][j], grid[i][j-1]);
}
}
std::cout << grid[m-1][n-1] << std::endl;Solution
Step 1: Calculate first column cumulative sums
grid[1][0] = grid[1][0] + grid[0][0] = 1 + 1 = 2Step 2: Calculate first row cumulative sums
grid[0][1] = grid[0][1] + grid[0][0] = 3 + 1 = 4Step 3: Calculate inner cell minimum path sums
grid[1][1] = grid[1][1] + min(grid[0][1], grid[1][0]) = 5 + min(4, 2) = 5 + 2 = 7Final Answer:
7 -> Option AQuick Check:
Minimum path sum = 7 [OK]
- Not updating first row and column before inner cells
- Adding max instead of min
- Mixing indices i and j
std::vector grid = {{1, 2, 3}, {4, 5, 6}};
int m = grid.size();
int n = grid[0].size();
for (int i = 1; i < m; i++) grid[i][0] += grid[i-1][0];
for (int j = 1; j < n; j++) grid[0][j] += grid[0][j-1];
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
grid[i][j] += std::max(grid[i-1][j], grid[i][j-1]);
}
}
std::cout << grid[m-1][n-1] << std::endl;Solution
Step 1: Check the inner loop operation
The code uses std::max to update grid[i][j], but the problem requires minimum path sum, so std::min should be used.Step 2: Verify other parts
First row and column are correctly initialized, loops have correct ranges, and grid initialization is valid.Final Answer:
Using std::max instead of std::min in inner loop -> Option CQuick Check:
Use min for minimum path sum [OK]
- Confusing max and min functions
- Skipping first row/column initialization
- Off-by-one errors in loops
grid = {
{1, 3, 1, 2},
{1, 5, 1, 1},
{4, 2, 1, 3}
};
You can only move right or down. Calculate the minimum sum.Solution
Step 1: Compute first row and first column cumulative sums
First row: [1, 4, 5, 7] (1, 1+3=4, 4+1=5, 5+2=7) First column: [1, 2, 6] (1, 1+1=2, 2+4=6)Step 2: Calculate inner cells minimum path sums
Row 1, col 1: 5 + min(4,2) = 5 + 2 = 7 Row 1, col 2: 1 + min(5,7) = 1 + 5 = 6 Row 1, col 3: 1 + min(7,6) = 1 + 6 = 7 Row 2, col 1: 2 + min(7,6) = 2 + 6 = 8 Row 2, col 2: 1 + min(6,8) = 1 + 6 = 7 Row 2, col 3: 3 + min(7,7) = 3 + 7 = 10Final Answer:
10 -> Option BQuick Check:
Minimum path sum = 10 [OK]
- Adding max instead of min
- Incorrect cumulative sums for first row/column
- Misindexing grid cells
Ready to prove it?
Pass the test and this pattern moves unknown
