为递归代码添加DP记忆化后结果错误,求排查(LeetCode网格递增路径)
问题原因分析及修正方案
你的代码在启用记忆化后结果错误,核心问题在于DP状态定义错误和路径数计算逻辑混乱,具体如下:
关键错误点
路径数累加逻辑错误
原代码中每次处理相邻单元格时,用count=1+solve(...)覆盖之前的结果,这会丢失其他方向的路径数。比如同时存在右方和下方两个递增方向时,第二个方向的计算会直接覆盖第一个方向的结果,而非累加。
正确逻辑应该是:从当前单元格出发的路径数 = 1(自身作为长度为1的路径) + 所有符合条件的相邻单元格的路径数之和(每个相邻单元格的路径都可以接在当前单元格后面)。DP状态与外部参数绑定
原代码传递了count参数,导致记忆化存储的dp[i][j]依赖于外部传入的初始值,这完全违背了DP状态的独立性——dp[i][j]应该固定表示从(i,j)出发的所有严格递增路径总数,与调用时的外部参数无关。不必要的DP数组扩容
你初始化了grid.size()+1×grid[0].size()+1的DP数组,虽然不会直接导致错误,但完全没必要,直接使用与网格同尺寸的数组即可。
修正后的代码
class Solution { public: const int MOD = 1e9+7; int solve(vector<vector<int>>& dp, vector<vector<int>>& grid, int i, int j) { // 记忆化:已计算过直接返回 if (dp[i][j] != -1) return dp[i][j]; long long res = 1; // 基础路径:自身单独作为一条路径 // 遍历四个方向 if (i+1 < grid.size() && grid[i+1][j] > grid[i][j]) res = (res + solve(dp, grid, i+1, j)) % MOD; if (j+1 < grid[0].size() && grid[i][j+1] > grid[i][j]) res = (res + solve(dp, grid, i, j+1)) % MOD; if (i-1 >= 0 && grid[i-1][j] > grid[i][j]) res = (res + solve(dp, grid, i-1, j)) % MOD; if (j-1 >= 0 && grid[i][j-1] > grid[i][j]) res = (res + solve(dp, grid, i, j-1)) % MOD; // 存储当前单元格的路径数并返回 return dp[i][j] = res % MOD; } int countPaths(vector<vector<int>>& grid) { long long ans = 0; int m = grid.size(), n = grid[0].size(); vector<vector<int>> dp(m, vector<int>(n, -1)); // 累加所有单元格的路径数 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { ans = (ans + solve(dp, grid, i, j)) % MOD; } } return ans % MOD; } };
修正说明
- DP状态明确:
dp[i][j]固定表示从(i,j)出发的所有严格递增路径总数,包括自身长度为1的路径。 - 正确累加逻辑:初始值为1(自身路径),然后将每个符合条件的相邻单元格的路径数累加,确保所有延伸路径都被统计。
- 移除冗余参数:删除了不必要的
count参数,DP状态的计算完全独立于外部调用传入的值。
内容的提问来源于stack exchange,提问作者Nikhil Sharma
相关产品推荐
相关产品推荐

