64_最小路径和

"""
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例:
输入:
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
"""


# 二维动态规划
def minPathSum1(grid):
    m = len(grid)
    n = len(grid[0])

    dp = [[0]*n]+[[0]*(n) for _ in range(m-1)]

    for i in range(m-1, -1,-1):
        for j in range(n-1, -1, -1):
            if i == m-1 and j != n-1:
                dp[i][j] = grid[i][j] + dp[i][j+1]
            elif j == n-1 and i != m -1:
                dp[i][j] = grid[i][j] + dp[i+1][j]
            elif j != n-1 and i != m-1:
                dp[i][j] = grid[i][j] + min(dp[i+1][j], dp[i][j+1])
            else:
                dp[i][j] = grid[i][j]

    return dp[0][0]
# 时间复杂度o(mn)
# 空间复杂度o(mn)

# 一维动态规划
def minPathSum2(grid):
    m = len(grid)
    n = len(grid[0])

    dp = [0]*(n)

    for i in range(m-1, -1,-1):
        for j in range(n-1, -1, -1):
            if i == m-1 and j != n-1:
                dp[j] = grid[i][j] + dp[j+1]
            elif j == n-1 and i != m -1:
                dp[j] = grid[i][j] + dp[j]
            elif j != n-1 and i != m-1:
                dp[j] = grid[i][j] + min(dp[j], dp[j+1])
            else:
                dp[j] = grid[i][j]

    return dp[0]
# 时间复杂度o(mn)
# 空间复杂度o(n)


# 动态规划(不需要额外存储空间)
def minPathSum3(grid):
    m = len(grid)
    n = len(grid[0])
    for i in range(m-1, -1,-1):
        for j in range(n-1, -1, -1):
            if i == m-1 and j != n-1:
                grid[i][j] = grid[i][j] + grid[i][j+1]
            elif j == n-1 and i != m -1:
                grid[i][j] = grid[i][j] + grid[i+1][j]
            elif j != n-1 and i != m-1:
                grid[i][j] = grid[i][j] + min(grid[i+1][j], grid[i][j+1])

    return grid[0][0]


# 自底向上
def minPathSum4(grid):
    if not grid:
        return 0
    row = len(grid)
    col = len(grid[0])

    dp = [[0]*col for _ in range(row)]
    dp[0][0] = grid[0][0]
    # 第一行
    for j in range(1, col):
        dp[0][j] = dp[0][j-1] + grid[0][j]
    # 第一列
    for i in range(1, row):
        dp[i][0] = dp[i-1][0] + grid[i][0]

    for i in range(1, row):
        for j in range(1, col):
            dp[i][j] = min(dp[i-1][j], dp[i][j-1]+grid[i][j])

    return dp[-1][-1]


# 自顶向下
def minPathSum5(grid):
    import functools
    if not grid:
        return 0
    row = len(grid)
    col = len(grid[0])
    @functools.lru_cache(None)
    def helper(i, j):
        if i == row-1 and j == col-1:
            return grid[i][j]
        if i >= row or j >= col:
            return float("inf")
        tmp = 0
        tmp += grid[i][j] + min(helper(i, j+1), helper(i+1, j))
        return tmp

    return helper(0, 0)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值