一、题目描述
Given a m x n grid filled with non-negative numbers,
find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
Input:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Output: 7
Explanation: Because the path 1→3→1→1→1 minimizes the sum.
二、题解
方法一:递归(超时)
递归三部曲:
- 结束条件:遇到网格最后一格。
- 本层递归的责任:
- 边界区域:只能往下面或者右边走。
- 非边界区域:有两种选择,取二者的最小权值。
- 返回值:当前位置权值 + 下一步的权值。
代码已删…
方法二:记忆化搜索
定义 memo 数组把一些重复计算的结果记忆下来,留给后面的的递归使用。
private int search(int[][] grid, int r, int c) {
if (memo[r][c] != 0)
return memo[r][c];
if (r == m - 1 && c == n - 1) {
memo[r][c] = grid[r][c];
return grid[r][c];
}
if (r == m - 1) { //到达最右一列,只能向下走
memo[r][c] = grid[r][c] + search(grid, r, c + 1);
return memo[r][c];
}
if (c == n - 1) { //到达最后一行,只能向右走
memo[r][c] = grid[r][c] + search(grid, r - 1, c);
return memo[r][c];
} //非边界区域
memo[r][c] = grid[r][c] + Math.min(search(grid, r, c + 1), search(grid, r + 1, c));
return memo[r][c];
}
复杂度分析
- 时间复杂度:O(m∗n)O(m * n)O(m∗n),
- 空间复杂度:O(m∗n)O(m * n)O(m∗n),
方法三:bfs(超时)
- 定义内部类 Pos,存储网格每个点的坐标以 (x, y) 及当前所走过的路径的权值总和 sum。
- bfs 从结点 (0, 0) 开始,每次添加两个方向的结点,直到网格的终点。
- 到达终点 (m−1,n−1)(m-1, n-1)(m−1,n−1) 后,如果路径权值总和比 minSum 小,那么更新 minSum 为当前权值。
方法四:dp
基于方法二,我们可以把程序从递归改为迭代,原理都一样。
动态规划三部曲:
-
状态定义:dp[i][j] 的值代表直到走到 (i,j) 的最小路径和。
-
转移方程:
- 起点: dp[i][j] = grid[i][j]
- 非矩阵边界: dp[i][j] = grid[i][j] + min(dp[i - 1][j], dp[i][j - 1])
- 左边是矩阵边界:即 i = 0,j != 0 时,dp[i][j] = dp[i][j−1] + grid[i][j]
- 上边是矩阵边界: 即 i != 0,j == 0 时,dp[i][j] = dp[i - 1][j] + grid[i][j]
-
初始状态: dp[0][0] = grid[0][0]
class Solution {
public:
int minPathSum(vector<vector<int>>& g) {
int n = g.size(), m = g[0].size(), f[n+1][m+1];
memset(f, 0, sizeof f);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
if (i == 0 && j == 0)f[i][j] = g[i][j];
else if (j == 0) f[i][j] = f[i-1][j] + g[i][j]; //从左边来
else if (i == 0) f[i][j] = f[i][j-1] + g[i][j];//从上面来
else f[i][j] = min(f[i-1][j], f[i][j-1]) + g[i][j];
}
return f[n-1][m-1];
}
};
复杂度分析
- 时间复杂度:O(m×n)O(m × n)O(m×n),
- 空间复杂度:O(m×n)O(m × n)O(m×n),