前情提要:
所有的 题目来源 leetcode,同学可以自行通过题目跳转链接自己做题,让我们共同进步吧~

==================
快速跳转:
我的个人博客主页👉:Reuuse博客
新开专栏👉:Java算法专栏
❀ 感谢支持!☀
==================

不同路径
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?

🚀题目解析

即:求从左上到右下有几种方案
⭐算法原理
dp[i][j] 表示,走到[i, j]位置的时候一共有多少路径

状态转移方程: dp[i][j] = dp[i-1][j] + dp[i][j-1]
初始化
目的:填表不越界
开辟数组时,外围新增虚拟数组
- 虚拟节点的值,保证后面填表结果正确
- 下标的映射,横纵坐标+1

填表顺序
- 从上往下填写
- 从左往右填写
🍃代码实现
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m+1][n+1];
dp[0][1] = 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];
return dp[m][n];
}
}
不同路径Ⅱ
给定一个 m x n 的整数数组 grid。一个机器人初始位于 左上角(即 grid[0][0])。机器人尝试移动到 右下角(即 grid[m - 1][n - 1])。机器人每次只能向下或者向右移动一步。
网格中的障碍物和空位置分别用 1 和 0 来表示。机器人的移动路径中不能包含 任何 有障碍物的方格。
返回机器人能够到达右下角的不同路径数量。
测试用例保证答案小于等于 2 * 109。

🚀题目解析
新增了障碍物的情况下有几种路径
⭐算法原理
dp[i][j] 表示,走到[i, j]位置的时候一共有多少路径

🍃代码实现
class Solution {
public int uniquePathsWithObstacles(int[][] ob) {
int m = ob.length, n = ob[0].length;
int[][] dp = new int[m+1][n+1];
dp[0][1] = 1;
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
if(ob[i-1][j-1] == 0) //没有障碍物
dp[i][j] = dp[i-1][j] + dp[i][j-1];
return dp[m][n];
}
}
珠宝的最大价值
现有一个记作二维矩阵 frame 的珠宝架,其中 frame[i][j] 为该位置珠宝的价值。拿取珠宝的规则为:
只能从架子的左上角开始拿珠宝
每次可以移动到右侧或下侧的相邻位置
到达珠宝架子的右下角时,停止拿取
注意:珠宝的价值都是大于 0 的。除非这个架子上没有任何珠宝,比如 frame = [[0]]。
🚀题目解析

在路径问题上加上了求和
⭐算法原理
dp[i][j] 表示,走到[i, j]位置的时候,此时的最大价值

状态转移方程: dp[i][j] = max(dp[i-1][j] + dp[i][j-1]) + g[i][j]
🍃代码实现
class Solution {
public int jewelleryValue(int[][] grid) {
int m = grid.length, n = grid[0].length;
int[][] dp = new int[m+1][n+1];
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j]) + grid[i-1][j-1];
return dp[m][n];
}
}
下降路径最小和
给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径 的 最小和 。
下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)、(row + 1, col) 或者 (row + 1, col + 1) 。
🚀题目解析
这个元素只能往 左下 下 右下 的方式走

⭐算法原理
dp[i][j] 表示,走到[i, j]位置时,最小的下降路径

状态转移方程: dp[i][j] = min(x, y, z) + m[i][j]
初始化

- 加上一行,加上两列
- 所有位置 改为 +∞
- 第一行改为 0
填表顺序 :从上往下
返回值:最后一行的最小值
🍃代码实现
class Solution {
public int minFallingPathSum(int[][] matrix) {
int n = matrix.length;
int[][] dp = new int[n+1][n+2];
//初始化
for(int i = 1; i <= n; i++)
dp[i][0] = dp[i][n+1] = Integer.MAX_VALUE;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
dp[i][j] = Math.min(dp[i-1][j], Math.min(dp[i-1][j-1], dp[i-1][j+1])) + matrix[i-1][j-1];
int ret = Integer.MAX_VALUE;
for(int j = 1; j <=n ; j++)
ret = Math.min(ret, dp[n][j]);
return ret;
}
}
最小路径和
给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
🚀题目解析

⭐算法原理
dp[i][j] 表示,到达[i, j]位置时,最小路径和

状态转移方程: dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + g[i][j]
初始化:

填表顺序: 从上往下,从左往右
返回值: dp[m][n]
🍃代码实现
class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length, n = grid[0].length;
int[][] dp = new int[m+1][n+1];
//初始化第一行
for(int j = 0; j <= n; j++) dp[0][j] = Integer.MAX_VALUE;
//初始化第一列
for(int i = 0; i <= m; i++) dp[i][0] = Integer.MAX_VALUE;
dp[0][1] = dp[1][0] = 0;
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + grid[i-1][j-1];
return dp[m][n];
}
}
地下城游戏
恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。
骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。
有些房间由恶魔守卫,因此骑士在进入这些房间时会失去健康点数(若房间里的值为负整数,则表示骑士将损失健康点数);其他房间要么是空的(房间里的值为 0),要么包含增加骑士健康点数的魔法球(若房间里的值为正整数,则表示骑士将增加健康点数)。
为了尽快解救公主,骑士决定每次只 向右 或 向下 移动一步。
返回确保骑士能够拯救到公主所需的最低初始健康点数。
注意:任何房间都可能对骑士的健康点数造成威胁,也可能增加骑士的健康点数,包括骑士进入的左上角房间以及公主被监禁的右下角房间。
🚀题目解析

⭐算法原理
- 以某个位置为结尾
dp[i][j]表示,从起点出发,到达[i, j]位置时,所需最低初始健康点数
可以发现状态一直在更改,完全推不出来,所以需要另一个方式
- 以某个位置为起点
dp[i][j]表示,从[i, j]位置出发,到达终点,所需最低初始健康点数

状态转移方程: dp[i][j] = min(dp[i][j=1], dp[i=][j]) - d[i][j]
特殊情况: 若d[i][j] 值过大导致结果大于0;且 dp[i][j] 是处于负数的情况下,则不符合题意(如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。)
- 增加判断:
dp[i][j] = max(1, dp[i][j])
初始化:

填表顺序: 从下往上,从右往左
返回值: dp[0][0]
🍃代码实现
class Solution {
public int calculateMinimumHP(int[][] d) {
int m = d.length, n = d[0].length;
int[][] dp = new int[m+1][n+1];
//初始化最后一行
for(int j = 0; j <= n; j++) dp[m][j] = Integer.MAX_VALUE;
//初始化最后一列
for(int i = 0; i <= m; i++) dp[i][n] = Integer.MAX_VALUE;
dp[m][n-1] = dp[m-1][n] = 1;
for(int i = m-1; i >= 0; i--)
for(int j = n-1; j >= 0; j--)
{
dp[i][j] = Math.min(dp[i][j+1], dp[i+1][j]) - d[i][j];
dp[i][j] = Math.max(dp[i][j], 1);
}
return dp[0][0];
}
}
一个小小的赞是对我大大滴支持~
1233

被折叠的 条评论
为什么被折叠?



