python - leetcode - 64. Minimum path and [Classic problem solution - matrix array dynamic programming]

1. Topic: 64. Minimum path sum

Description:
Given an mxn grid containing non-negative integers, please find a path from the upper left corner to the lower right corner such that the sum of the numbers on the path is minimum.

Note: You can only move one step down or right at a time.
Example 1:
Insert image description here

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 13111 的总和最小。

Example 2:

输入:grid = [[1,2,3],[4,5,6]]
输出:12

hint:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 200
  • 0 <= grid[i][j] <= 200

2. Problem-solving ideas

Since the direction of the path can only be down or to the right, each element in the first row of the grid can only be reached from the upper left corner element by moving to the right, and each element in the first column of the grid can only be reached from the upper left corner. The corner element starts to move downward. The path at this time is unique, so the sum of the minimum paths corresponding to each element is the sum of the numbers on the corresponding paths.

For an element that is not in the first row or column, it can be reached by moving one step down from the adjacent element above it, or by moving one step to the right from the adjacent element to its left. The sum of the minimum paths corresponding to the element is equal to the sum of the adjacent elements above it and its The minimum value of the sum of the minimum paths corresponding to the two adjacent elements on the left plus the value of the current element. Since the minimum path corresponding to each element is related to the sum of the minimum paths corresponding to its adjacent elements, dynamic programming can be used to solve it.

Create a two-dimensional array
Insert image description here

Finally, the value of dp[m−1][n−1] is obtained, which is the sum of the minimum paths from the upper left corner of the grid to the lower right corner of the grid.

3. Code examples

class Solution(object):
    def minPathSum(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        # 解法一, 空间优化
        m, n = len(grid), len(grid[0])
        for i in range(1, n):  # 第一行初始化
            grid[0][i] = grid[0][i] + grid[0][i - 1]
        for i in range(1, m):  # 第一列初始化
            grid[i][0] = grid[i][0] + grid[i - 1][0]
        for i in range(1, m):  # 对剩下的格子进行填充
            for j in range(1, n):
                grid[i][j] = grid[i][j] + min(grid[i - 1][j], grid[i][j - 1])
        return grid[-1][-1]

		# 解法二
        if not grid or not grid[0]:
            return 0
        rows, columns = len(grid), len(grid[0])
        dp = [[0] * columns 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, columns):
            dp[0][j] = dp[0][j - 1] + grid[0][j]
        for i in range(1, rows):
            for j in range(1, columns):
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]
        return dp[rows - 1][columns - 1]

		# 解法三
        m, n = len(grid), len(grid[0])
        # 状态定义:dp[i][j] 表示从 [0,0] 到 [i,j] 的最小路径和
        dp = [[0] * n for _ in range(m)]
        # 状态初始化
        dp[0][0] = grid[0][0]
        # 状态转移
        for i in range(m):
            for j in range(n):
                if i == 0 and j != 0:
                    dp[i][j] = grid[i][j] + dp[i][j - 1]
                elif i != 0 and j == 0:
                    dp[i][j] = grid[i][j] + dp[i - 1][j]
                elif i != 0 and j != 0:
                    dp[i][j] = grid[i][j] + min(dp[i - 1][j], dp[i][j - 1])
        # 返回结果
        return dp[m - 1][n - 1]

Guess you like

Origin blog.csdn.net/qq_43030934/article/details/131682071