学习动态规划不同路径、最小路径和、打家劫舍、打家劫舍iii
2023-12-31 05:13:27
学习动态规划|不同路径、最小路径和、打家劫舍、打家劫舍iii
62 不同路径
- 动态规划,dp[i][j]表示从左上角到(i,j)的路径数量
- dp[i][j] = dp[i-1][j] + dp[i][j-1]
import java.util.Arrays;
/**
* 路径数量
* 动态规划,dp[i][j]表示从左上角到(i,j)的路径数量
* dp[i][j] = dp[i-1][j] + dp[i][j-1]
*/
public class $62 {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
//边界
for (int i = 0; i < m; i++) {
dp[i][0] = 1;
}
for (int i = 0; i < n; i++) {
dp[0][i] = 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-1][n-1];
}
public int uniquePaths2(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];
}
}
import java.util.Arrays;
/**
* 路径数量
* 动态规划,dp[i][j]表示从左上角到(i,j)的路径数量
* dp[i][j] = dp[i-1][j] + dp[i][j-1]
*/
public class $62 {
public int uniquePaths2(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];
}
}
64 最小路径和
- 动态规划,dp[i][j]表示从左上角到(i,j)的最小路径和
- grid[i][j] = Math.min(grid[i-1][j], grid[i][j-1]) + grid[i][j]
/**
* 最小路径和
* grid[i][j] = Math.min(grid[i-1][j], grid[i][j-1]) + grid[i][j]
*/
public class $64 {
public int minPathSum(int[][] grid) {
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (i==0 && j==0) continue;
else if (i!=0 && j==0) grid[i][j] = grid[i-1][j] + grid[i][j];
else if (i==0 && j!=0) grid[i][j] = grid[i][j-1] + grid[i][j];
else grid[i][j] = Math.min(grid[i-1][j], grid[i][j-1]) + grid[i][j];
}
}
return grid[grid.length-1][grid[0].length-1];
}
}
198 打家劫舍
- 动态规划,nums[i]表示前i间房屋能偷窃到的最高总金额
- nums[i] = Math.max(nums[i-1], nums[i-2]+nums[i]);
/**
* 打家劫舍
* 动态规划,nums[i]表示前i间房屋能偷窃到的最高总金额
* nums[i] = Math.max(nums[i-1], nums[i-2]+nums[i]);
*/
public class $198 {
public int rob(int[] nums) {
//注意特殊值0,1
if (nums == null || nums.length == 0) {
return 0;
}
if (nums.length == 1) {
return nums[0];
}
//nums[1]为nums[0]、nums[1]的最大值
nums[1] = Math.max(nums[0], nums[1]);
//从nums[2]开始
for (int i = 2; i < nums.length; i++) {
nums[i] = Math.max(nums[i-1], nums[i-2]+nums[i]);
}
return nums[nums.length-1];
}
}
337 打家劫舍iii
- 树形动态规划
- 我们可以用 f(o)表示选择 o节点的情况下,o节点的子树上被选择的节点的最大权值和;
- g(o)表示不选择 o节点的情况下,o节点的子树上被选择的节点的最大权值和;
- l 和 r代表 o 的左右孩子。
- 当 o 被选中时:o 的左右孩子都不能被选中,
-
故 o 被选中情况下子树上被选中点的最大权值和为 l和 r不被选中的最大权值和 + o的值
-
f(o)=g(l)+g(r)+o.val
- 当 o不被选中时,o的左右孩子可以被选中,也可以不被选中。
-
对于 o的某个具体的孩子 x,它对 o 的贡献是 x被选中和不被选中情况下权值和的较大值。
-
g(o)=max{f(l),g(l)} + max{f(r),g(r)}
import java.util.HashMap;
import java.util.Map;
/**
* 打家劫舍iii
* 树形动态规划
* 我们可以用 f(o)表示选择 o节点的情况下,o节点的子树上被选择的节点的最大权值和;
* g(o)表示不选择 o节点的情况下,o节点的子树上被选择的节点的最大权值和;
* l 和 r代表 o 的左右孩子。
*
* 当 o 被选中时:o 的左右孩子都不能被选中,
* 故 o 被选中情况下子树上被选中点的最大权值和为 l和 r不被选中的最大权值和 + o的值
* f(o)=g(l)+g(r)+o.val
* 当 o不被选中时,o的左右孩子可以被选中,也可以不被选中。
* 对于 o的某个具体的孩子 x,它对 o 的贡献是 x被选中和不被选中情况下权值和的较大值。
* g(o)=max{f(l),g(l)} + max{f(r),g(r)}
*/
public class $337 {
Map<TreeNode, Integer> f = new HashMap<>();
Map<TreeNode, Integer> g = new HashMap<>();
public int rob(TreeNode root) {
process(root);
return Math.max(f.getOrDefault(root, 0), g.getOrDefault(root, 0));
}
private void process(TreeNode root) {
if (root == null) {
return;
}
process(root.left);
process(root.right);
f.put(root, root.val + g.getOrDefault(root.left, 0) + g.getOrDefault(root.right, 0));
g.put(root, Math.max(f.getOrDefault(root.left, 0), g.getOrDefault(root.left, 0))
+ Math.max(f.getOrDefault(root.right, 0), g.getOrDefault(root.right, 0)));
}
//法一的简化版
public int rob2(TreeNode root) {
int[] rootStatus = process2(root);
return Math.max(rootStatus[0], rootStatus[1]);
}
private int[] process2(TreeNode root) {
if (root == null) {
return new int[]{0, 0};
}
int[] l = process2(root.left);
int[] r = process2(root.right);
int selected = root.val + l[1] + r[1];
int notSelected = Math.max(l[0], l[1]) + Math.max(r[0], r[1]);
return new int[]{selected, notSelected};
}
}
文章来源:https://blog.csdn.net/weixin_43217281/article/details/135311217
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!