Start learning free

LESSON 294 OF 410 · MEMOIZATION

Minimum Path Sum II in JavaScript (O(n * m) Time Complexity)

Practice O(n2) - Memoization Read the full explanation

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

Note: You can only move either down or right at any point in time.

Example:

Input:
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
Output: 7
Explanation: Because the path 1→3→1→1→1 minimizes the sum.

Note:

Add memoization to the previous recursive solution, so every cell is computed only once. Your algorithm should run in O(n * m) time and use O(n * m) extra space.


STEP 1 OF 8
    Ctrl + Enter to check

    JAVASCRIPT · MEMOIZATION

    Minimum Path Sum in JavaScript, explained

    Understanding the Problem

    The core challenge of this problem is to find the path from the top-left corner to the bottom-right corner of a grid that results in the minimum sum of the numbers along the path. The constraints are that you can only move either down or right at any point in time.

    This problem is significant in various applications such as robotics (finding the shortest path in a grid), game development (pathfinding algorithms), and operations research (optimizing routes).

    Potential pitfalls include misunderstanding the movement constraints and not properly handling the grid boundaries.

    Approach

    To solve this problem, we can use dynamic programming. The idea is to create a 2D array (dp) where each cell dp[i][j] represents the minimum path sum to reach that cell from the top-left corner.

    We can start by initializing the top-left cell with the value of the grid's top-left cell. Then, we iterate through the grid, updating each cell in the dp array with the minimum sum to reach that cell.

    Initially, a naive solution might involve recursively exploring all possible paths, but this would be highly inefficient with a time complexity of O(2^(n+m)). Instead, we use dynamic programming to reduce the time complexity to O(n * m).

    Algorithm

    1. Create a 2D array dp with the same dimensions as the grid.

    2. Initialize the top-left cell of dp with the value of the top-left cell of the grid.

    3. Iterate through the grid, updating each cell in dp with the minimum sum to reach that cell.

    4. The value in the bottom-right cell of dp will be the minimum path sum.

    Code Implementation

    /**
     * @param {number[][]} grid
     * @return {number}
     */
    function minPathSum(grid) {
        const m = grid.length;
        const n = grid[0].length;
        
        // Create a 2D array to store the minimum path sums
        const dp = Array.from({ length: m }, () => Array(n).fill(0));
        
        // Initialize the top-left cell
        dp[0][0] = grid[0][0];
        
        // Fill the first row
        for (let j = 1; j < n; j++) {
            dp[0][j] = dp[0][j - 1] + grid[0][j];
        }
        
        // Fill the first column
        for (let i = 1; i < m; i++) {
            dp[i][0] = dp[i - 1][0] + grid[i][0];
        }
        
        // Fill the rest of the dp array
        for (let i = 1; i < m; i++) {
            for (let j = 1; j < n; j++) {
                dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
            }
        }
        
        // The bottom-right cell contains the minimum path sum
        return dp[m - 1][n - 1];
    }
    
    // Example usage:
    const grid = [
        [1, 3, 1],
        [1, 5, 1],
        [4, 2, 1]
    ];
    console.log(minPathSum(grid)); // Output: 7
    

    Complexity Analysis

    The time complexity of this solution is O(n * m) because we iterate through each cell of the grid once. The space complexity is also O(n * m) due to the additional 2D array used to store the minimum path sums.

    Edge Cases

    Potential edge cases include:

    • Empty grid: The function should handle an empty grid by returning 0.
    • Single row or single column grid: The function should correctly handle grids with only one row or one column.

    Examples:

    // Edge case: Empty grid
    console.log(minPathSum([])); // Output: 0
    
    // Edge case: Single row grid
    console.log(minPathSum([[1, 2, 3]])); // Output: 6
    
    // Edge case: Single column grid
    console.log(minPathSum([[1], [2], [3]])); // Output: 6
    

    Testing

    To test the solution comprehensively, we should include a variety of test cases, from simple to complex. We can use testing frameworks like Jest or Mocha for automated testing.

    Example test cases:

    const assert = require('assert');
    
    // Test case 1: Example grid
    assert.strictEqual(minPathSum([
        [1, 3, 1],
        [1, 5, 1],
        [4, 2, 1]
    ]), 7);
    
    // Test case 2: Empty grid
    assert.strictEqual(minPathSum([]), 0);
    
    // Test case 3: Single row grid
    assert.strictEqual(minPathSum([[1, 2, 3]]), 6);
    
    // Test case 4: Single column grid
    assert.strictEqual(minPathSum([[1], [2], [3]]), 6);
    
    console.log('All test cases pass');
    

    Thinking and Problem-Solving Tips

    When approaching such problems, it's essential to break down the problem into smaller subproblems and think about how to solve each subproblem efficiently. Dynamic programming is a powerful technique for optimizing recursive solutions by storing intermediate results.

    To develop problem-solving skills, practice solving similar problems and study various algorithms. Platforms like LeetCode, HackerRank, and CodeSignal offer a wide range of problems to practice.

    Conclusion

    In this blog post, we discussed how to solve the "Minimum Path Sum II" problem using dynamic programming. We covered the problem definition, approach, algorithm, code implementation, complexity analysis, edge cases, and testing. Understanding and solving such problems is crucial for improving problem-solving skills and preparing for technical interviews.

    Keep practicing and exploring further to enhance your skills!

    Additional Resources

    Keep going with JavaScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free