Minimum Path Sum in Grid in DSA Python - 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.
def min_path_sum(grid):
rows, cols = len(grid), len(grid[0])
dp = [[0]*cols for _ in range(rows)]
dp[0][0] = grid[0][0]
for i in range(1, rows):
dp[i][0] = dp[i-1][0] + grid[i][0]
for j in range(1, cols):
dp[0][j] = dp[0][j-1] + grid[0][j]
for i in range(1, rows):
for j in range(1, cols):
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
return dp[-1][-1]
This code calculates the smallest sum of numbers along 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 that fill the dp table by checking previous cells.
- How many times: Each cell in the grid is visited once, so rows x cols times.
As the grid size grows, the number of operations grows with the total number of cells.
| Input Size (n 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 because every cell is processed once.
Time Complexity: O(m x n)
This means the time needed grows proportionally with the number of cells in the grid.
[X] Wrong: "The time complexity is exponential because there are many paths to check."
[OK] Correct: The code uses dynamic programming to avoid repeating work, so it only processes each cell once, not all paths.
Understanding this time complexity shows you can analyze grid-based dynamic programming problems, a common skill interviewers look for.
"What if we allowed moving diagonally as well? How would the time complexity change?"
Practice
Given a grid of numbers, find the path from top-left to bottom-right with the smallest sum. Which best describes the path allowed?Solution
Step 1: Understand the problem constraints
The problem states you can only move right or down from each cell in the grid.Step 2: Identify the path type
This means the path is restricted to moves that go either to the right or downward, no other directions allowed.Final Answer:
Only moves right or down at each step -> Option CQuick Check:
Allowed moves = right or down [OK]
- Thinking diagonal moves are allowed
- Assuming moves can go left or up
- Ignoring movement restrictions
dp with zeros for a grid of size m rows and n columns?Solution
Step 1: Understand 2D list initialization
We want a list with m rows and n columns, so outer list length is m, inner list length is n.Step 2: Check each option
dp = [[0]*n for _ in range(m)] uses list comprehension to create m separate lists each of length n filled with 0, which is correct. dp = [[0]*m for _ in range(n)] swaps m and n. dp = [[0]*n]*m creates shallow copies causing shared inner lists. dp = [0]*m*n creates a flat list, not 2D.Final Answer:
dp = [[0]*n for _ in range(m)] -> Option BQuick Check:
Correct 2D zero list = [[0]*n for _ in range(m)] [OK]
- Using [[0]*n]*m causing shared references
- Swapping m and n dimensions
- Creating a flat list instead of 2D
grid = [[1,3,1],[1,5,1],[4,2,1]]
dp = [[0]*3 for _ in range(3)]
dp[0][0] = grid[0][0]
for i in range(1,3):
dp[0][i] = dp[0][i-1] + grid[0][i]
for j in range(1,3):
dp[j][0] = dp[j-1][0] + grid[j][0]
for i in range(1,3):
for j in range(1,3):
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
print(dp[2][2])Solution
Step 1: Fill first row and column of dp
dp[0][0]=1; dp[0][1]=1+3=4; dp[0][2]=4+1=5; dp[1][0]=1+1=2; dp[2][0]=2+4=6Step 2: Calculate dp values for inner cells
dp[1][1]=min(dp[0][1],dp[1][0])+5=min(4,2)+5=7; dp[1][2]=min(dp[0][2],dp[1][1])+1=min(5,7)+1=6; dp[2][1]=min(dp[1][1],dp[2][0])+2=min(7,6)+2=8; dp[2][2]=min(dp[1][2],dp[2][1])+1=min(6,8)+1=7Final Answer:
7 -> Option DQuick Check:
Minimum path sum = 7 [OK]
- Mixing up indices i and j
- Adding instead of taking minimum
- Incorrect initialization of dp
def minPathSum(grid):
m, n = len(grid), len(grid[0])
dp = [[0]*n]*m
dp[0][0] = grid[0][0]
for i in range(1, m):
dp[i][0] = dp[i-1][0] + grid[i][0]
for j in range(1, n):
dp[0][j] = dp[0][j-1] + grid[0][j]
for i in range(1, m):
for j in range(1, n):
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
return dp[m-1][n-1]Solution
Step 1: Analyze dp initialization
dp = [[0]*n]*m creates m references to the same inner list, so updating one row updates all rows.Step 2: Consequence of shallow copy
When dp[i][0] or dp[0][j] is updated, all rows change, causing incorrect path sums.Final Answer:
dp initialization uses shallow copy causing wrong updates -> Option AQuick Check:
Use list comprehension for dp initialization [OK]
- Using shallow copy for 2D lists
- Incorrect loop ranges
- Returning wrong dp cell
grid = [[2,1,3],[6,5,4],[7,8,9]]
Write a function to find the minimum path sum from top-left to bottom-right moving only right or down. What is the minimum path sum?
Solution
Step 1: Initialize dp and fill first row and column
dp[0][0]=2; first row: dp[0][1]=2+1=3, dp[0][2]=3+3=6; first column: dp[1][0]=2+6=8, dp[2][0]=8+7=15Step 2: Fill remaining dp cells
dp[1][1]=min(dp[0][1],dp[1][0])+5=min(3,8)+5=8; dp[1][2]=min(dp[0][2],dp[1][1])+4=min(6,8)+4=10; dp[2][1]=min(dp[1][1],dp[2][0])+8=min(8,15)+8=16; dp[2][2]=min(dp[1][2],dp[2][1])+9=min(10,16)+9=19Final Answer:
19 -> Option AQuick Check:
Minimum path sum = 19 [OK]
- Incorrect dp initialization
- Mixing up indices in loops
- Adding max instead of min
Ready to prove it?
Pass the test and this pattern moves unknown
