You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带顺序跳跃的网格最短路径遍历实现修复与提速咨询

网格最短路径问题解答

问题梳理

从网格左下角(0,0)出发到右上角(X-1,Y-1),合法移动规则为:向右移动1格、向上移动1格、按给定jumps数组顺序依次完成向上/向右跳跃(跳跃步长为jump值+1格,跳过的中间格子不计入路径和),路径总长度为途经所有格子数值之和,要求输出最短路径总长度。
示例输入:

Grid: 
    [9 9 1]
    [9 9 1]    
    [3 9 1]
Jumps: [1 1] X:3, Y:3

对应输出为5,逻辑如题干所述。

现有代码问题分析

第一版递归解法问题

你的第一版递归本质是暴力DFS,存在大量重复子问题,时间复杂度为指数级,网格稍大就会超时甚至无法终止。同时没有显式记录已使用的跳跃次数,递归状态不完整,实际运行中也可能出现逻辑错误。

第二版DP解法问题

存在三个核心错误:

  1. 状态维度缺失:跳跃需要按顺序使用,同一坐标(y,x)在已使用k个跳跃和已使用m个跳跃的场景下,最小路径和完全不同,你只用二维DP存储坐标维度,丢失了跳跃使用进度的关键状态。
  2. 全局修改jumps数组逻辑错误:不同路径使用跳跃的时机不同,你直接全局修改jumps数组,相当于所有路径共享同一个跳跃使用进度,完全不符合实际场景。
  3. 语法逻辑错误:判断if min == jumpup or min == jumpright中的min是Python内置函数,你实际要比较的是前面计算得到的shortest变量,这里的判断完全不生效。

高效实现方案

这里提供修正后的三维DP方案,时间复杂度为O(KXY),其中K为jumps数组长度,完全可以应对中等规模以上的输入:

三维DP思路

定义三维状态dp[k][y][x]:表示已使用前k个跳跃,到达坐标(y,x)时的最小路径和。

  1. 初始化:所有状态初始化为无穷大,起点状态dp[0][0][0] = grid[0][0]
  2. 状态转移:
    • 普通移动:对于任意状态dp[k][y][x],向上走1格到(y+1,x),可更新dp[k][y+1][x] = min(dp[k][y+1][x], dp[k][y][x] + grid[y+1][x]);向右走1格到(y,x+1),可更新dp[k][y][x+1] = min(dp[k][y][x+1], dp[k][y][x] + grid[y][x+1])
    • 跳跃移动:如果k < len(jumps),可以使用第k个跳跃:向上跳jumps[k]+1格到y + jumps[k] + 1,如果不越界,可更新dp[k+1][y + jumps[k] + 1][x] = min(dp[k+1][y + jumps[k] + 1][x], dp[k][y][x] + grid[y + jumps[k] + 1][x]);向右跳同理。
  3. 最终结果:所有dp[k][Y-1][X-1](k的取值范围是0到len(jumps))中的最小值。

代码实现

def min_path_sum(grid, jumps, X, Y):
    K = len(jumps)
    INF = float('inf')
    # dp[k][y][x] 用了k个jump,到(y,x)的最小和
    dp = [[[INF]*X for _ in range(Y)] for __ in range(K+1)]
    dp[0][0][0] = grid[0][0]
    
    for k in range(K+1):
        # 迭代更新当前k下所有坐标的最小路径和,直到没有更新
        updated = True
        while updated:
            updated = False
            for y in range(Y):
                for x in range(X):
                    if dp[k][y][x] == INF:
                        continue
                    # 向上走
                    if y + 1 < Y:
                        if dp[k][y+1][x] > dp[k][y][x] + grid[y+1][x]:
                            dp[k][y+1][x] = dp[k][y][x] + grid[y+1][x]
                            updated = True
                    # 向右走
                    if x + 1 < X:
                        if dp[k][y][x+1] > dp[k][y][x] + grid[y][x+1]:
                            dp[k][y][x+1] = dp[k][y][x] + grid[y][x+1]
                            updated = True
        # 处理当前k可以跳跃的情况,生成k+1层的状态
        if k < K:
            jump_val = jumps[k]
            for y in range(Y):
                for x in range(X):
                    if dp[k][y][x] == INF:
                        continue
                    # 向上跳
                    new_y = y + jump_val + 1
                    if new_y < Y:
                        if dp[k+1][new_y][x] > dp[k][y][x] + grid[new_y][x]:
                            dp[k+1][new_y][x] = dp[k][y][x] + grid[new_y][x]
                    # 向右跳
                    new_x = x + jump_val + 1
                    if new_x < X:
                        if dp[k+1][y][new_x] > dp[k][y][x] + grid[y][new_x]:
                            dp[k+1][y][new_x] = dp[k][y][x] + grid[y][new_x]
    # 取所有可能的k到达终点的最小值
    return min(dp[k][Y-1][X-1] for k in range(K+1))

# 测试示例
grid = [
    [3,9,1],
    [9,9,1],
    [9,9,1]
]
jumps = [1,1]
X=3
Y=3
print(min_path_sum(grid, jumps, X, Y)) # 输出5
jumps = [1]
print(min_path_sum(grid, jumps, X, Y)) # 输出6

如果grid数值全为正数,也可以使用Dijkstra算法优化,以路径和为权重,优先队列每次取出当前最小路径和的状态扩展,首次到达终点即可直接返回结果,效率更高。

内容的提问来源于stack exchange,提问作者Pryver Johnson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 18:30:02