作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/minimum-path-sum/description/

题目描述

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.

题目大意

求一个矩阵从左上角到右下角的最短路径和。

解题方法

第一感觉是dfs,但是题目没有说范围,估计会超时。然后就想到了DP。

使用DP创建了一个path数组,和grid数组是一样的。path代表了从左上角开始到某个点的最短路径。那么很容易知道,新的一个点的最短路径一定等于其上方、左方最短路径+当前的值。因此写成双重循环即可。因为要用到上方、左方的值,数组第一行和第一列会超出边框,其实只需要把这个方向设为前面的那个路径值即可。

这个算法的时间啊复杂度是O(m * n),空间复杂度是O(m * n)。

代码如下:

class Solution:
def minPathSum(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
if not grid or not grid[0]: return 0
m, n = len(grid), len(grid[0])
path = copy.deepcopy(grid)
for i in range(m):
for j in range(n):
if i == 0 and j == 0:
before = 0
elif i == 0:
before = path[i][j-1]
elif j == 0:
before = path[i-1][j]
else:
before = min(path[i-1][j], path[i][j-1])
path[i][j] = before + grid[i][j]
return path[m-1][n-1]

发现path数组没有必要重新复制出来,可以直接使用grid代表了。这样实际上就对grid进行了一个覆盖:遍历过的地方代表path,还没遍历到的地方代表grid。

这个算法的时间复杂度是O(m * n),空间复杂度是O(1)。由于少了复制数组的一步,事实上真的变快了。

class Solution:
def minPathSum(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
if not grid or not grid[0]: return 0
m, n = len(grid), len(grid[0])
for i in range(m):
for j in range(n):
if i == 0 and j == 0:
before = 0
elif i == 0:
before = grid[i][j-1]
elif j == 0:
before = grid[i-1][j]
else:
before = min(grid[i-1][j], grid[i][j-1])
grid[i][j] = before + grid[i][j]
return grid[m-1][n-1]

二刷的时候使用的C++,方法仍然是动态规划,第一行的每个状态等于左边状态+当前位置,和第一列的每个状态等于上边状态+当前位置。其余位置等于上边和左边的状态最小值加上当前位置。

C++代码如下:

class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
const int M = grid.size(), N = grid[0].size();
vector<vector<int>> dp(M, vector<int>(N, 0));
dp[0][0] = grid[0][0];
for (int i = 1; i < M; ++i)
dp[i][0] = dp[i - 1][0] + grid[i][0];
for (int j = 0; j < N; ++j)
dp[0][j] = dp[0][j - 1] + grid[0][j];
for (int i = 1; i < M; ++i) {
for (int j = 1; j < N; ++j) {
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
}
}
return dp[M - 1][N - 1];
}
};

参考资料:

日期

2018 年 9 月 11 日 —— 天好阴啊
2018 年 12 月 29 日 —— 2018年剩余电量不足1%

【LeetCode】64. Minimum Path Sum 解题报告(Python & C++)的更多相关文章

  1. LeetCode: Minimum Path Sum 解题报告

    Minimum Path Sum Given a m x n grid filled with non-negative numbers, find a path from top left to b ...

  2. leetCode 64.Minimum Path Sum (最短路) 解题思路和方法

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...

  3. [LeetCode] 64. Minimum Path Sum 最小路径和

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...

  4. LeetCode 64. Minimum Path Sum(最小和的路径)

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...

  5. LeetCode 64 Minimum Path Sum

    Problem: Given a m x n grid filled with non-negative numbers, find a path from top left to bottom ri ...

  6. C#解leetcode 64. Minimum Path Sum

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...

  7. [leetcode]64. Minimum Path Sum最小路径和

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...

  8. [leetcode] 64. Minimum Path Sum (medium)

    原题 简单动态规划 重点是:grid[i][j] += min(grid[i][j - 1], grid[i - 1][j]); class Solution { public: int minPat ...

  9. leecode 每日解题思路 64 Minimum Path Sum

    题目描述: 题目链接:64 Minimum Path Sum 问题是要求在一个全为正整数的 m X n 的矩阵中, 取一条从左上为起点, 走到右下为重点的路径, (前进方向只能向左或者向右),求一条所 ...

随机推荐

  1. lsof之列出已打开的文件

    lsof命令常用解析 Linux中常用 lsof 来查看文件调用进程等相关信息,也可用来查看活跃的进程信息和端口监听进程信息等 1. lsof 命令介绍 NAME lsof - list open f ...

  2. 字符串String的trim()方法

    用来删除字符串两端的空白字符并返回,trim方法并不影响原来的字符串本身,它返回的是一个新的字符串 String a = "  Hello World  "; String b = ...

  3. day11 四层负载均衡和http协议

    day11 四层负载均衡和http协议 四层负载均衡和七层负载均衡的区别 四层和七层负载均衡的区别 四层负载均衡数据包在底层就进行了分发,而七层负载均衡数据包则是在最顶层进行分发.由此可以看出,七层负 ...

  4. 什么是 IP 地址 – 定义和解释

    IP 地址定义 IP 地址是一个唯一地址,用于标识互联网或本地网络上的设备.IP 代表"互联网协议",它是控制通过互联网或本地网络发送的数据格式的一组规则. 本质上,IP 地址是允 ...

  5. android studio 编译NDK android studio 生成.so文件

    详细配置使用请移步:https://www.jianshu.com/p/4c7d9a10933b android studio NDK 编译 第一步: app/build.gradle下面 添加代码: ...

  6. Output of C++ Program | Set 10

    Predict the output of following C++ programs. Question 1 1 #include<iostream> 2 #include<st ...

  7. Linux:$i 和 ${i}区别

    例如你要把有个变量的值和其他字符串连接起来,就需要用到{},以明示{}中的是一个变量. 例如: export var1=ABC export var2=var1=${var1} echo $var2 ...

  8. HCL华三模拟器静态路由实验

    (copy自我的其他博客网站) 拓扑如下: 实验目的:通过给A.B.C三台路由器配置静态路由,使PC1可以ping通PC2. 实验环境:Windows10 (21H1),HCL(V3.0.1) 实验步 ...

  9. Mysql脚本 优化检测

    下载地址: wget https://launchpad.net/mysql-tuning-primer/trunk/1.6-r1/+download/tuning-primer.sh 安装依赖: y ...

  10. Memcached 状态机分析

    worker线程拿到了这个连接之后,就应该是分配给这个连接一个结构体,包括这个连接所有的状态,都写buf等,这个结构体就是conn,然后这个worker线程会在它自己的event_base加入对这个新 ...