Minimum Path Sum

Solve this Problem
Medium15–20 min
Topics
Companies
Practice:LeetCode ↗GFG ↗
Given a grid where every cell holds a non-negative cost, and starting at the top-left corner with only right and down moves allowed, find the minimum possible total cost of any path to the bottom-right corner — the sum of every cell's cost along the way, including both endpoints. Every cell's cheapest total is its own cost plus whichever of the two cells that could lead into it — the one above, or the one to its left — offers the cheaper cost so far. The very first row and first column each only have one possible way in (straight along the edge), so their running totals are just a simple accumulation of costs with no comparison needed. Filling in the grid this way, one row at a time, means every cell's cheapest cost is already known by the time a later cell needs to compare against it, and the bottom-right corner ends up holding the answer.

Test Case 1:

Input:grid = [[2,4,1],[5,3,2],[1,6,3]]
Output:12
Explanation:The path 2→4→1→2→3 (right, right, down, down) totals 12, the smallest sum of any right/down route.

Test Case 2:

Input:grid = [[5,2],[7,3]]
Output:10
Explanation:The path 5→2→3 (right, down) totals 10, beating 5→7→3 (down, right) which totals 15.

Test Case 3:

Input:grid = [[9]]
Output:9
Explanation:A single-cell grid has only one possible path: the cell itself.

Constraints

  • 1 ≤ grid.length, grid[0].length ≤ 50
  • 0 ≤ grid[i][j] ≤ 100
🚀

Try the Dry Run

Don't just read the solution — watch it execute, one step at a time.

Approach & Solutions

Brute Force — Recursive Without Memoization

Brute

Standing on any cell, the cheapest way to finish from there is that cell's own cost plus whichever of the two possible next moves — one step down or one step right — ends up cheaper overall. Reaching the bottom-right corner costs exactly that cell's own value, since there's nowhere left to go. Stepping past the bottom or right edge of the grid isn't a valid move, so that direction is simply excluded from the comparison whenever it would go out of bounds. Recursing from the top-left corner and always taking the cheaper of the two next moves at every cell finds the minimum total, though the same cell's cheapest cost ends up recomputed every time a different path reaches it.

TimeO(2^(m+n))
SpaceO(m + n)
1class Solution { 2 private int[][] grid; 3 private int m; 4 private int n; 5 6 public int minPathSum(int[][] grid) { 7 this.grid = grid; 8 this.m = grid.length; 9 this.n = grid[0].length; 10 return solve(0, 0); 11 } 12 13 private int solve(int i, int j) { 14 if (i == m - 1 && j == n - 1) return grid[i][j]; 15 if (i >= m || j >= n) return Integer.MAX_VALUE; 16 int down = solve(i + 1, j); 17 int right = solve(i, j + 1); 18 return grid[i][j] + Math.min(down, right); 19 } 20}

Optimal — Bottom-Up 1D DP

Optimal

Track, for the row currently being processed, the cheapest cost to reach each column from the top-left corner. The very first column of every row can only be reached by moving straight down, so its cost simply adds this cell's value to whatever cost is already there from the row above. Every other cell chooses the cheaper of two arrivals — from above (the value already sitting at this column) or from the left (the value just computed at the previous column in this same row) — and adds its own cost on top. Sweeping through every row this way, the last column ends up holding the minimum total cost to the bottom-right corner.

TimeO(m × n)
SpaceO(n)
1class Solution { 2 public int minPathSum(int[][] grid) { 3 int m = grid.length, n = grid[0].length; 4 int[] dp = new int[n]; 5 Arrays.fill(dp, Integer.MAX_VALUE); 6 dp[0] = 0; 7 for (int i = 0; i < m; i++) { 8 for (int j = 0; j < n; j++) { 9 if (j == 0) { 10 dp[j] = dp[j] + grid[i][j]; 11 } else { 12 dp[j] = Math.min(dp[j], dp[j - 1]) + grid[i][j]; 13 } 14 } 15 } 16 return dp[n - 1]; 17 } 18}

Related Problems