【动态规划】【leetcode】64. Minimum Path Sum

1. 题目描述

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.

2. 算法分析

假设我们从(0,0)开始沿某一条路径到达位置(i,j)处,获得最小的和。我们把这个和记为f(i,j)。那么针对f(i,j)有下面两条规则

  1. 首先,如果i,j均为0的话,那么显然f(0,0) = grid[0][0]
  2. 因此题目规定,路径只能向右或者向下。那么想要到达(i,j)这个位置,必须先到达(i-1,j)处或者(i, j-1)处。因此到达(i,j)的最小路径和应该是f(i,j) = min{f(i -1, j), f(i, j - 1 )} + grid[i][j]
    基于这两条规则,我们可以写出代码

3.代码实现1

class Solution():
    def minPathSum(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        row = len(grid)
        # 防止输入grid == []
        if (row == 0):
            return 0    
        # 防止输入grid == [[]]
        colum = len(grid[0])
        if (row == 0 or colum == 0):
            return 0
        res = [[0 for i in range(colum)] for j in range(row)] 
        for i in range(row):
            for j in range(colum):
                if (i == 0 and j == 0):
                    res[i][j] = grid[0][0]
                else:
                    if i == 0:
                        res[i][j] = res[i][j - 1] + grid[i][j]
                    elif j == 0:
                        res[i][j] = res[i - 1][j] + grid[i][j]
                    else:
                        res[i][j] = min(res[i - 1][j], res[i][j - 1]) + grid[i][j]
        return res[row - 1][colum - 1]

grid = [[1,3,1],[1,5,1],[4,2,1]]
res = Solution()
ans = res.minPathSum(grid)

在这段代码当中,我们初始化了一个跟grid维度一样的二维列表,用这个列表来记录到达(i,j)位置的最小路径和。事实上,直接在原来的grid列表中记录就可以了,完全没有必要申请这样一个列表,这样可以大幅提高速度,同时节省内存空间。这个在当时刷题时没有想到。那么我们可以把代码改进一下

代码实现2(改进)

class Solution():
    def minPathSum(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        row = len(grid)
        if (row == 0):
            return 0    
        colum = len(grid[0])
        if (row == 0 or colum == 0):
            return 0 
        for i in range(row):
            for j in range(colum):
                if (i == 0 and j == 0):
                    continue
                else:
                    if i == 0:
                        grid[i][j] = grid[i][j - 1] + grid[i][j]
                    elif 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[row - 1][colum - 1]

grid = [[1,3,1],[1,5,1],[4,2,1]]
res = Solution()
ans = res.minPathSum(grid)
print(ans);        
全部评论

相关推荐

威猛的小饼干正在背八股:挂到根本不想整理
点赞 评论 收藏
分享
10-18 13:01
已编辑
西安理工大学 C++
小米内推大使:建议技能还是放上面吧,hr和技术面试官第一眼想看的应该是技能点和他们岗位是否匹配
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务