Minimum Path Sum in Grid in DSA Go - 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.
func minPathSum(grid [][]int) int {
m, n := len(grid), len(grid[0])
for i := 1; i < m; i++ {
grid[i][0] += grid[i-1][0]
}
for j := 1; j < n; j++ {
grid[0][j] += grid[0][j-1]
}
for i := 1; i < m; i++ {
for j := 1; j < n; j++ {
if grid[i-1][j] < grid[i][j-1] {
grid[i][j] += grid[i-1][j]
} else {
grid[i][j] += grid[i][j-1]
}
}
}
return grid[m-1][n-1]
}
This code finds the minimum sum 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 traversing the grid cells.
- How many times: The outer loop runs m times, and the inner loop runs n times, covering all cells.
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 | About 100 operations |
| 100 x 100 | About 10,000 operations |
| 1000 x 1000 | About 1,000,000 operations |
Pattern observation: Doubling the grid size roughly quadruples the work, because work grows with the number of cells.
Time Complexity: O(m * n)
This means the time needed grows proportionally to the total number of cells in the grid.
[X] Wrong: "The time grows only with the number of rows or columns, not both."
[OK] Correct: The code visits every cell in the grid, so both rows and columns affect the total steps.
Understanding this time complexity helps you explain how your solution scales and why it is efficient for grid problems.
"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 to find the path from the top-left corner to the bottom-right corner of a grid that has the smallest total sum of the numbers on the path.Step 2: Recognize allowed moves
Only moves to the right or down are allowed, so the path must follow these directions.Final Answer:
The smallest sum of numbers from the top-left to bottom-right moving only right or down -> Option CQuick Check:
Minimum path sum = smallest total sum [OK]
- Thinking diagonal moves are allowed
- Looking for largest sum instead of smallest
- Counting all numbers instead of path sum
Solution
Step 1: Check correct 2D slice initialization
grid := [][]int{{1, 3, 1}, {1, 5, 1}, {4, 2, 1}} uses [][]int with nested slices, which is the correct way to declare a 2D slice in Go.Step 2: Identify incorrect options
grid := [3][3]int{{1, 3, 1}, {1, 5, 1}, {4, 2, 1}} uses fixed array type which is valid but less flexible; grid := [][]int{1, 3, 1, 1, 5, 1, 4, 2, 1} is a flat slice, not 2D; grid := []int{ {1, 3, 1}, {1, 5, 1}, {4, 2, 1} } uses []int with nested braces which is invalid syntax.Final Answer:
grid := [][]int{{1, 3, 1}, {1, 5, 1}, {4, 2, 1}} -> Option DQuick Check:
2D slice with nested slices = correct grid init [OK]
- Using flat slices instead of 2D slices
- Incorrect array type syntax
- Missing nested braces for rows
func minPathSum(grid [][]int) int {
m, n := len(grid), len(grid[0])
for i := 1; i < m; i++ {
grid[i][0] += grid[i-1][0]
}
for j := 1; j < n; j++ {
grid[0][j] += grid[0][j-1]
}
for i := 1; i < m; i++ {
for j := 1; j < n; j++ {
if grid[i-1][j] < grid[i][j-1] {
grid[i][j] += grid[i-1][j]
} else {
grid[i][j] += grid[i][j-1]
}
}
}
return grid[m-1][n-1]
}
func main() {
grid := [][]int{{1,3,1},{1,5,1},{4,2,1}}
fmt.Println(minPathSum(grid))
}Solution
Step 1: Calculate first column cumulative sums
grid[1][0] = 1+1=2, grid[2][0] = 2+4=6Step 2: Calculate first row cumulative sums
grid[0][1] = 1+3=4, grid[0][2] = 4+1=5Step 3: Calculate remaining cells minimum path sums
grid[1][1] = min(4,2)+5=7, grid[1][2] = min(5,7)+1=6, grid[2][1] = min(7,6)+2=8, grid[2][2] = min(6,8)+1=7Final Answer:
7 -> Option AQuick Check:
Minimum path sum = 7 [OK]
- Not updating first row and column sums
- Adding max instead of min
- Mixing indices in loops
func minPathSum(grid [][]int) int {
m, n := len(grid), len(grid[0])
for i := 1; i <= m; i++ {
grid[i][0] += grid[i-1][0]
}
for j := 1; j <= n; j++ {
grid[0][j] += grid[0][j-1]
}
for i := 1; i < m; i++ {
for j := 1; j < n; j++ {
if grid[i-1][j] < grid[i][j-1] {
grid[i][j] += grid[i-1][j]
} else {
grid[i][j] += grid[i][j-1]
}
}
}
return grid[m-1][n-1]
}Solution
Step 1: Identify loop boundary error
The loops use <= which causes index out of range error because valid indices are 0 to m-1 and 0 to n-1.Step 2: Fix loop conditions
Changing loops to use < instead of <= prevents out of range access and correctly iterates over grid indices.Final Answer:
Change loops to use < instead of <= for i and j -> Option BQuick Check:
Loop indices must be less than length [OK]
- Using <= causing index out of range
- Not checking array bounds
- Returning wrong grid cell
[[1, 0, 3], [0, 5, 1], [4, 2, 0]]Choose the correct statement.
Solution
Step 1: Understand zero cost cell effect
Cells with zero cost add no extra sum, so paths passing through them can have lower total sums.Step 2: Confirm algorithm behavior
The algorithm sums cell values; zero values reduce total sum, so zero cost cells help find cheaper paths.Final Answer:
Zero cost cells can reduce the minimum path sum by providing cheaper paths -> Option AQuick Check:
Zero cost cells lower path sum [OK]
- Ignoring zero cells in sum
- Assuming zero causes errors
- Thinking zero increases cost
Ready to prove it?
Pass the test and this pattern moves unknown
