Minimum Path Sum — Solution in Python, Java & C++
Minimum Path Sum solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A medium problem.
Minimum Path Sum is a medium coding problem on arrays, dynamic programming and matrix, asked in Amazon, Google, Microsoft and Rubrik interviews.
- Difficulty: Medium
- Topics: Arrays, Dynamic Programming, Matrix
- Asked at: Amazon, Google, Microsoft, Rubrik, Goldman Sachs, Dropbox
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
Given an m × n grid of non-negative numbers, find a path from the top-left corner to the bottom-right corner that minimises the sum of the numbers along it.
You may only move down or right at each step. Return that minimum sum.
Example 1
Input: grid = [[1,3,1],[1,5,1],[4,2,1]]
Output: 7
Explanation: The path 1 → 3 → 1 → 1 → 1 sums to 7.
Example 2
Input: grid = [[1,2,3],[4,5,6]]
Output: 12
Example 3
Input: grid = [[5]]
Output: 5
Constraints
1 <= grid.length, grid[i].length <= 80 <= grid[i][j] <= 200
Hints for Minimum Path Sum
Hint 1
A cell is reachable only from above or from the left, so its best cost is its own value plus the cheaper of those two.
Hint 2
The first row and first column have exactly one way in — fill them as running sums first.
Hint 3
You can overwrite the grid in place, since every cell is read only by cells below and to the right.
How to solve Minimum Path Sum
A cell is entered from above or from the left, so its best cost is its value plus the cheaper of those two predecessors.
Approach
- Fill the first row and first column as running sums — each has one way in.
- For every other cell,
dp[r][c] = grid[r][c] + min(dp[r-1][c], dp[r][c-1]). - Return
dp[m-1][n-1].
Why it works
With only down and right moves, every path to (r, c) passes through exactly one of (r-1, c) or (r, c-1) last, so the optimal cost decomposes over that choice. Row-major order ensures both predecessors are ready.
Complexity
- Time —
O(m · n) - Space —
O(m · n), or O(1) extra by overwriting the grid
Pitfalls
- Greedy (always take the smaller neighbour) is wrong — a cheap step can lead into an expensive corridor.
Reference solution
Python
def minPathSum(grid) -> int:
m, n = len(grid), len(grid[0])
dp = [row[:] for row in grid]
for c in range(1, n):
dp[0][c] += dp[0][c - 1]
for r in range(1, m):
dp[r][0] += dp[r - 1][0]
for r in range(1, m):
for c in range(1, n):
dp[r][c] += min(dp[r - 1][c], dp[r][c - 1])
return dp[m - 1][n - 1]Java
public static int minPathSum(int[][] grid) {
int m = grid.length, n = grid[0].length;
int[][] dp = new int[m][n];
for (int r = 0; r < m; r++) {
for (int c = 0; c < n; c++) dp[r][c] = grid[r][c];
}
for (int c = 1; c < n; c++) dp[0][c] += dp[0][c - 1];
for (int r = 1; r < m; r++) dp[r][0] += dp[r - 1][0];
for (int r = 1; r < m; r++) {
for (int c = 1; c < n; c++) {
dp[r][c] += Math.min(dp[r - 1][c], dp[r][c - 1]);
}
}
return dp[m - 1][n - 1];
}C++
int minPathSum(vector<vector<int>>& grid) {
int m = (int) grid.size(), n = (int) grid[0].size();
vector<vector<int>> dp = grid;
for (int c = 1; c < n; c++) dp[0][c] += dp[0][c - 1];
for (int r = 1; r < m; r++) dp[r][0] += dp[r - 1][0];
for (int r = 1; r < m; r++) {
for (int c = 1; c < n; c++) {
dp[r][c] += min(dp[r - 1][c], dp[r][c - 1]);
}
}
return dp[m - 1][n - 1];
}JavaScript
var minPathSum = function(grid) {
const m = grid.length, n = grid[0].length;
const dp = [];
for (let r = 0; r < m; r++) dp.push(grid[r].slice());
for (let c = 1; c < n; c++) dp[0][c] += dp[0][c - 1];
for (let r = 1; r < m; r++) dp[r][0] += dp[r - 1][0];
for (let r = 1; r < m; r++) {
for (let c = 1; c < n; c++) {
dp[r][c] += Math.min(dp[r - 1][c], dp[r][c - 1]);
}
}
return dp[m - 1][n - 1];
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 1199 arrays problems · the whole catalogue
Learn the technique: Arrays · Dynamic Programming