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

如何在Minimum Path Sum问题中实现最小和路径的查找与打印(Python)

最小路径和问题

给定一个m×n的非负整数网格,找出一条从左上角到右下角的路径,使得路径上所有数字的和最小。
输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:路径1 → 3 → 1 → 1 → 1的和最小。

问题

能否用Python打印出这条1 → 3 → 1 → 1 → 1的路径?

现状

能计算最小路径和,但无法打印路径。尝试用BFS实现,但解决方案未考虑路径权重(即路径和),代码如下:

def bfs(grid):
    queue = collections.deque([[(0,0)]])
    seen = set([(0,0)])
    while queue:
        path = queue.popleft()
        x, y = path[-1]
        if (x,y) == (width-1, height-1):
            return path
        for x2, y2 in ((x+1,y), (x-1,y), (x,y+1), (x,y-1)):
            if 0 <= x2 < width and 0 <= y2 < height and (x2, y2) not in seen:
                queue.append(path + [(x2, y2)])
                seen.add((x2, y2))

解决方案

你原来的BFS只关注路径步数,没考虑路径和的权重,所以无法找到最小和路径。下面提供两种可行的实现方式:

方法一:动态规划+回溯记录路径

通过动态规划记录每个位置的最小路径和,同时记录该位置的前驱坐标,最后从终点回溯到起点得到路径。

def min_path_sum_with_path(grid):
    m = len(grid)
    n = len(grid[0]) if m > 0 else 0
    if m == 0 or n == 0:
        return []
    
    # dp[i][j]存储到达(i,j)的最小路径和,prev[i][j]存储前驱坐标
    dp = [[0]*n for _ in range(m)]
    prev = [[None]*n for _ in range(m)]
    
    dp[0][0] = grid[0][0]
    # 填充第一行
    for j in range(1, n):
        dp[0][j] = dp[0][j-1] + grid[0][j]
        prev[0][j] = (0, j-1)
    # 填充第一列
    for i in range(1, m):
        dp[i][0] = dp[i-1][0] + grid[i][0]
        prev[i][0] = (i-1, 0)
    # 填充其他区域
    for i in range(1, m):
        for j in range(1, n):
            if dp[i-1][j] < dp[i][j-1]:
                dp[i][j] = dp[i-1][j] + grid[i][j]
                prev[i][j] = (i-1, j)
            else:
                dp[i][j] = dp[i][j-1] + grid[i][j]
                prev[i][j] = (i, j-1)
    
    # 从终点回溯路径
    path = []
    current = (m-1, n-1)
    while current is not None:
        path.append(grid[current[0]][current[1]])
        current = prev[current[0]][current[1]]
    # 反转得到从起点到终点的顺序
    path.reverse()
    return path

# 测试
grid = [[1,3,1],[1,5,1],[4,2,1]]
path = min_path_sum_with_path(grid)
print(" → ".join(map(str, path)))  # 输出:1 → 3 → 1 → 1 → 1

方法二:Dijkstra算法(带权重的优先队列)

利用优先队列每次弹出当前路径和最小的节点,直到到达终点,适合非负权重的网格场景。

import heapq

def min_path_sum_dijkstra(grid):
    m = len(grid)
    n = len(grid[0]) if m > 0 else 0
    if m == 0 or n == 0:
        return []
    
    # 优先队列元素:(当前路径和, x坐标, y坐标, 当前路径列表)
    heap = []
    heapq.heappush(heap, (grid[0][0], 0, 0, [grid[0][0]]))
    # 记录每个位置的最小路径和,避免重复处理
    min_sum = [[float('inf')]*n for _ in range(m)]
    min_sum[0][0] = grid[0][0]
    
    # 仅考虑向右、向下移动(向上/向左会增加路径长度,不可能得到最小和)
    directions = [(1,0), (0,1)]
    while heap:
        current_sum, x, y, path = heapq.heappop(heap)
        if x == m-1 and y == n-1:
            return path
        for dx, dy in directions:
            nx, ny = x + dx, y + dy
            if 0 <= nx < m and 0 <= ny < n:
                new_sum = current_sum + grid[nx][ny]
                if new_sum < min_sum[nx][ny]:
                    min_sum[nx][ny] = new_sum
                    heapq.heappush(heap, (new_sum, nx, ny, path + [grid[nx][ny]]))
    return []

# 测试
grid = [[1,3,1],[1,5,1],[4,2,1]]
path = min_path_sum_dijkstra(grid)
print(" → ".join(map(str, path)))  # 输出:1 → 3 → 1 → 1 → 1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 09:12:02