一、算法介绍
最短路径问题是在图中寻找连接两个节点的具有最小代价的路径。路径的代价可以是边的权重之和,也可以是其他度量标准,例如时间、距离等。
最短路径问题可以用图论中的经典算法来解决,常见的有迪杰斯特拉算法(Dijkstra's algorithm)、贝尔曼-福特算法(Bellman-Ford algorithm)和弗洛伊德算法(Floyd-Warshall algorithm)等。
-
迪杰斯特拉算法:
- 初始化起点的距离为0,其他节点的距离为无穷大。
- 对于所有未访问的节点,选择距离起点最近的节点,并标记为已访问。
- 遍历该节点的邻居节点,并更新其距离,如果经过当前节点到达邻居节点的路径比之前的更短,则更新距离。
- 重复上述步骤,直到所有节点都被访问完毕或者找到目标节点,此时最短路径即可得到。
-
贝尔曼-福特算法:
- 初始化起点的距离为0,其他节点的距离为无穷大。
- 对于所有节点,遍历图中的每条边,将边的权重与起点到起点节点的距离加和进行比较,如果小于原先的距离,则更新距离。
- 重复上述步骤,直到没有任何距离更新或者经过一定的迭代次数。
- 最后,检查是否存在负权环,若存在则说明图中存在无限负权的最短路径。
-
弗洛伊德算法:
- 初始化距离矩阵,将已知的直接相连节点间的距离写入矩阵。
- 对于每对节点 i 和 j,检查通过其他节点 k 是否能够使得从 i 到 j 的路径更短,如果可以则更新距离矩阵中的值。
- 重复上述步骤,直到所有节点对之间的最短路径都被求解出。
这些算法的具体实现会有一些差异,但它们的基本原理都是通过逐步计算来找到连接两个节点的最短路径。选择算法时需要考虑图的特性、算法的时间复杂度以及实际应用场景等因素。
二、题目
题目来源见力扣
给定一个包含非负整数的 m x n
网格 grid
,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:一个机器人每次只能向下或者向右移动一步。
示例 1:
输入:grid = [[1,3,1],[1,5,1],[4,2,1]] 输出:7 解释:因为路径 1→3→1→1→1 的总和最小。
示例 2:
输入:grid = [[1,2,3],[4,5,6]] 输出:12
三、解题代码
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
m=len(grid)
n=len(grid[0])
res=[]
for i in range(m):
res.append([0]*n)
res[0][0]=grid[0][0]
for i in range(1,n):
res[0][i]=res[0][i-1]+grid[0][i]
for i in range(1,m):
res[i][0]=res[i-1][0]+grid[i][0]
for i in range(1,m):
for j in range(1,n):
res[i][j]=grid[i][j]+min(res[i-1][j],res[i][j-1])
return res[-1][-1]
四、补充
LCR 100. 三角形最小路径和 - 力扣(LeetCode)
给定一个三角形 triangle
,找出自顶向下的最小路径和。
每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i
,那么下一步可以移动到下一行的下标 i
或 i + 1
。
示例 1:
输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]] 输出:11 解释:如下面简图所示: 2 3 4 6 5 7 4 1 8 3 自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
示例 2:
输入:triangle = [[-10]] 输出:-10
class Solution:
def minimumTotal(self, triangle: List[List[int]]) -> int:
m=len(triangle)
n=len(triangle[m-1])
res=[]
for i in range(1,m+1):
res.append([0]*i)
res[0][0]=triangle[0][0]
for i in range(1,m):
res[i][0]=res[i-1][0]+triangle[i][0]
res[i][-1]=res[i-1][-1]+triangle[i][-1]
for i in range(2,m):
for j in range(1,i):
res[i][j]=triangle[i][j]+min(res[i-1][j-1],res[i-1][j])
return min(res[-1])