题目
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
思路
- 首先这道题目是一道动态规划的题目,如何判断? 很明显后边的结果依赖于前边的结果,所以可以递推得到最后的结果。
- 看到最短路径和这道题,就可以想到 BFS, (什么? 你想到Floyd和Dijkstra,还有更多其他的算法?关于这个问题,后边讨论)
- 还有人想到DFS?,这个先在这里说明一下,DFS 和 BFS,DFS 采用递归的形式,从一个节点走到头,然后再从下一个继续走。
注:由于这道题目不存在环路,所以可以采用的 dfs 和 bfs 的算法来计算最短路径,当存在环路时,还要存储重复访问某一点时,是否从相同路径过来的,否则就会陷入无限循环,编码就比较复杂,这时采用 Dijkstra 等算法就比较方便。更多解释可以参考链接:https://blog.csdn.net/sallyxyl1993/article/details/57077512
DFS 和 BFS 就好比:你站在一个多叉口,往前走。 DFS就是沿着一条路一直走,走完了再返回来重新走下一条。 BFS就是你多条路同时进度走,(假如有穿墙的技能)每条路都走一走。(当然,这个例子我觉得和题目比较相关,所以这么举例来说明区别,还有一个是在每个房间找钥匙的例子来说明区别,详细的可以参考 《大话数据结构》这本书)
继续:根据这个例子,可以想到,如果你要验证从起点能不能到达终点,dfs比较好,也就是图的连通性。判断哪条路比较近的话 dfs 和 bfs 理论上的时间复杂度是一样的,dfs 递归写法简单一些,但是有可能会爆栈。bfs采用队列,稍微复杂,比较稳定。碰到具体最短路径的问题,如果选项只有 bfs 和 dfs 的话,根据实际问题分析,可以两种算法思路都考虑一下,如果没什么差别的话,我一般选择BFS,(主要担心DFS爆栈,需要不断的剪枝优化)。
下图是时间复杂度的