NOTE

Minimum Path Sum

LeetCode notes on the Minimum Path Sum problem.

Data Structures & AlgorithmsCreated Updated 1 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

1. Problem Description

Given an m x n grid of non-negative integers, find a path from the top-left corner to the bottom-right corner such that the sum of the numbers along the path is minimized.

Note: You may only move one step down or right at a time.

2. Approach

  1. Approach 1
    • DFS: whenever reaching (i, j), add the number at that position to sum
    • Because movement is only right or down, the same (i, j) will not be revisited along one path, so no set is needed to record visited positions
  2. Approach 2
    • DFS + memoization
  3. Approach 3
    • Dynamic programming

3. Implementation

3.1. DFS

func minPathSum(grid [][]int) int {
    minCount := math.MaxInt32
    minPathSumDFS(grid, 0, 0, len(grid), len(grid[0]), 0, &minCount)
    return minCount
}

func minPathSumDFS(grid [][]int, row, col, m, n, currentCount int, minCount * int) {
    if invalid(row, col, m, n) {
        return
    }

    currentCount += grid[row][col]

    if exceedEnd(row, col, m, n) {
        *minCount = min(*minCount, currentCount)
        return
    }


    minPathSumDFS(grid, row+1, col, m, n, currentCount, minCount)
    minPathSumDFS(grid, row, col+1, m, n, currentCount, minCount)
}

func invalid(row, col, m, n int) bool {
    if row < 0 || row >= m || col < 0 || col >= n {
        return true
    }

    return false
}

func exceedEnd(row, col, m, n int) bool {
    return row==m-1 && col == n-1
}

func min(a, b int) int {
    if a < b {
        return a
    }

    return b
}

3.2. DFS + Memoization

func minPathSum(grid [][]int) int {
    memo := make(map[string]int, 0)
    return minPathSumDFS(grid, 0, 0, len(grid), len(grid[0]), memo)
}

func minPathSumDFS(grid [][]int, row, col, m, n int, memo map[string]int) int {
    count, ok := memo[getKey(row, col)]
    if ok {
        return count
    }

    if invalid(row, col, m, n) {
        return math.MaxInt32
    }

    if exceedEnd(row, col, m, n) {
        return grid[row][col]
    }



    minCount := math.MaxInt32
    minCount = min(minCount, minPathSumDFS(grid, row+1, col, m, n, memo))
    minCount = min(minCount, minPathSumDFS(grid, row, col+1, m, n, memo))

    if minCount == math.MaxInt32 {
        minCount = 0
    }

    memo[getKey(row, col)] = minCount + grid[row][col]
    return minCount + grid[row][col]
}

func invalid(row, col, m, n int) bool {
    if row < 0 || row >= m || col < 0 || col >= n {
        return true
    }

    return false
}

func getKey(row, col int) string {
    return fmt.Sprintf("%v:%v", row, col)
}


func exceedEnd(row, col, m, n int) bool {
    return row==m-1 && col == n-1
}

func min(a, b int) int {
    if a < b {
        return a
    }

    return b
}

3.3. Dynamic Programming

func minPathSum2(grid [][]int) int {
	for i := 0; i < len(grid); i++ {
		for j := 0; j < len(grid[0]); j++ {
			if i == 0 && j == 0 {
				continue
			} else if i == 0 {
				grid[i][j] = grid[i][j-1] + grid[i][j]
			} else if j == 0 {
				grid[i][j] = grid[i-1][j] + grid[i][j]
			} else {
				grid[i][j] = min(grid[i-1][j], grid[i][j-1]) + grid[i][j]
			}

		}
	}
	return grid[len(grid)-1][len(grid[0])-1]
}

func min(a int, b int) int {
	if a < b {
		return a
	}

	return b
}

4. References

Discussion

Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub