递归解法修正求助:最小路径和问题(附错误代码)
修正最小路径和的递归解法
我来帮你修正这个递归解法,先拆解下你原代码里的几个关键问题:
- 边界逻辑搞反了:你用
n>a or m>b判断越界,但网格是0索引的,比如3×3的网格,最大索引是(2,2),所以应该是n >= a或m >= b才是越界;而且终点判断完全缺失——当走到右下角(n == a-1且m == b-1)时,应该直接返回当前格子的值,这是递归的终止条件之一。 - 修改原网格导致数据污染:你直接在递归里执行
grid[n][m] += ...,这会把原网格的值改掉,后续递归调用时拿到的是已经累加过的错误值,彻底打乱了计算逻辑。 - 没有记忆化缓存:纯递归会重复计算大量相同的子问题(比如网格中间的格子会被多条路径重复访问计算),不仅效率极低,稍大的网格直接会超时。
- 代码语法不完整:你原代码里
minPath(grid,n,m+1...没写完,这也是明显的语法错误。
修正后的递归解法(带记忆化优化)
import math def minPathSum(grid): rows = len(grid) cols = len(grid[0]) if rows > 0 else 0 # 记忆化缓存:存储每个位置到终点的最小路径和,避免重复计算 memo = [[-1 for _ in range(cols)] for _ in range(rows)] def helper(current_row, current_col): # 越界情况:返回无穷大表示这条路径不可行 if current_row >= rows or current_col >= cols: return math.inf # 到达终点:直接返回当前格子的值 if current_row == rows - 1 and current_col == cols - 1: return grid[current_row][current_col] # 如果已经计算过这个位置的最小路径和,直接返回缓存值 if memo[current_row][current_col] != -1: return memo[current_row][current_col] # 计算向下走和向右走的最小路径和 down_path = helper(current_row + 1, current_col) right_path = helper(current_row, current_col + 1) # 当前位置的最小路径和 = 当前格子值 + 向下/向右的较小路径和 memo[current_row][current_col] = grid[current_row][current_col] + min(down_path, right_path) return memo[current_row][current_col] return helper(0, 0) # 测试示例 grid = [[1,3,1],[1,5,1],[4,2,1]] print(minPathSum(grid)) # 输出7,和预期一致
核心修正点说明
- 新增记忆化缓存
memo:每个格子的最小路径和只会计算一次,后续再访问直接取缓存,把时间复杂度从O(2^(m+n))降到了O(m×n),效率提升非常明显。 - 修正边界终止条件:明确区分越界不可达和到达终点的情况,确保递归能正确终止。
- 不修改原网格:所有计算都基于原始网格数据,缓存存储的是计算结果,不会污染输入数据。
- 封装递归逻辑:对外只需要传入网格即可,不需要手动传递当前位置和行列数,调用更简洁友好。
如果你想保留原函数的参数形式(手动传入当前位置和网格行列数),可以参考下面的版本:
import math def minPath(grid, n, m, rows, cols, memo): # 越界返回无穷大 if n >= rows or m >= cols: return math.inf # 到达终点返回当前值 if n == rows - 1 and m == cols - 1: return grid[n][m] # 缓存存在直接返回 if memo[n][m] != -1: return memo[n][m] down = minPath(grid, n+1, m, rows, cols, memo) right = minPath(grid, n, m+1, rows, cols, memo) memo[n][m] = grid[n][m] + min(down, right) return memo[n][m] # 调用方式 grid = [[1,3,1],[1,5,1],[4,2,1]] rows = len(grid) cols = len(grid[0]) memo = [[-1]*cols for _ in range(rows)] print(minPath(grid, 0, 0, rows, cols, memo)) # 输出7
内容的提问来源于stack exchange,提问作者Utkarsh Prakash




