62 不同路径
https://leetcode.cn/problems/unique-paths/description/
方法一,从右下向左上填,off by one,利用多出来的一行和一列为0相加不出界的性质。
方法二,从左上向右下填,首行和首列初始化为1。以下为空间降维后的写法。
class Solution { //方法一,从右下向左上填
public int uniquePaths(int m, int n) {
int[] dp = new int[n + 1];
dp[n - 1] = 1;
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >=0; j--) {
dp[j] += dp[j + 1];
}
}
return dp[0];
}
}
class Solution { //方法二,从左上向右下填
public int uniquePaths(int m, int n) {
int[] dp = new int[n];
Arrays.fill(dp, 1);
for (int i = 1; i < m; i++) {
for (int j = 1; j <n; j++) {
dp[j] += dp[j - 1];
}
}
return dp[n - 1];
}
}
63 不同路径 II
https://leetcode.cn/problems/unique-paths-ii/description/
class Solution { //方法一,从右下向左上填
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length, n = obstacleGrid[0].length;
int[][] dp = new int[m + 1][n + 1];
if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1) return 0;
dp[m - 1][n - 1] = 1;
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
if (i == m - 1 || obstacleGrid[i + 1][j] == 0) dp[i][j] += dp[i + 1][j];
if (j == n - 1 || obstacleGrid[i][j + 1] == 0) dp[i][j] += dp[i][j + 1];
}
}
return dp[0][0];
}
}
class Solution { //方法二,从左上向右下填
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length, n = obstacleGrid[0].length;
int[][] dp = new int[m + 1][n + 1];
dp[1][1] = obstacleGrid[0][0] == 1 ? 0 : 1; //bug
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (i == 1 && j == 1) continue; //跳过base case
if (obstacleGrid[i - 1][j - 1] == 0) dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m][n];
}
}