62. 不同路径 - 中等 - 10/8
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
解析: 动态规划
可以看出,每一个格子被经过的次数就是左侧格子的次数 + 上方格子的次数
题目中问总共有多少条不同的路径。如果我们知道怎么到达终点的上方,怎么到达终点的左侧,我们自然能知道有多少种方式可以到达终点。可以列出公式如下:
到达终点的路径数=到达终点左方的路径数+到达终点右方的路径数~(这也就是动态规划里面的状态方程)
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
//第一行都赋予 1
for(int i=0; i<n; i++) dp[0][i] = 1;
//第一列都赋予 1
for(int i=0; i<m; i++) dp[i][0] = 1;
//从上到下,从左到右的顺序
for(int i=1; i<m; i++){
for(int j=1; j<n; j++){
dp[i][j] = dp[i-1][j] + dp[i][j-1];
} 1
}
return dp[m-1][n-1];
}
}
时间复杂度:O(mn)
空间复杂度:O(mn)
64. 最小路径和 - 中等 - 10/9
给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
解析:动态规划
如果是上边界或者左边界,就直接累加;否则,就取两者最小值再累加。
class Solution {
public int minPathSum(int[][] grid) {
int width = grid[0].length, high = grid.length;
if(high == 0 || width == 0) return 0;
//初始化上边界
for(int i=1; i<width; i++) grid[0][i] += grid[0][i-1];
//初始化左边界
for(int i=1; i<high; i++) grid[i][0] += grid[i-1][0];
//既不是上边界也不是左边界
for(int i=1; i<high; i++){
for(int j=1; j<width; j++){
grid[i][j] += Math.min(grid[i-1][j],grid[i][j-1]);
}
}
return grid[high-1][width-1];
}
}
时间复杂度:O(m * n)。
空间复杂度:O(1)。