代码随想录算法训练营day48 | 198.打家劫舍,213.打家劫舍II,337.打家劫舍III

news/2024/11/8 15:13:10/

代码随想录算法训练营day48 | 198.打家劫舍,213.打家劫舍II,337.打家劫舍III

  • 198.打家劫舍
    • 解法一:动态规划
  • 213.打家劫舍II
    • 解法一:分别掐头和去尾,动态规划
  • 337.打家劫舍III
    • 解法一:树的递归遍历+动态规划
  • 总结


198.打家劫舍

教程视频:https://www.bilibili.com/video/BV1Te411N7SX
在这里插入图片描述
思路:
1、dp[i]定义:到第 i 间时能拿到的最大金额(此时房间号从0开始)
2、递推公式:当前dp[i]可从两个渠道获得:1、不拿nums[i];2、拿nums[i]。所以递推公式为dp[i]=Math.max(dp[i-1], dp[i-2]+nums[i]);
3、dp数组初始化:dp[0]=nums[0];dp[1]=Math.max(nums[0], nums[1]);(注意nums长度)
4、遍历顺序:当前金额由前面的金额决定,正序遍历房间
5、打印验证

解法一:动态规划

class Solution {public int rob(int[] nums) {int[] dp = new int[nums.length];//初始化dp[0]=nums[0];if(nums.length<2){return dp[0];}else{dp[1]=Math.max(nums[1],nums[0]);}for(int j=2;j<dp.length;j++){dp[j]=Math.max(dp[j-1], dp[j-2]+nums[j]);}return dp[dp.length-1];}
}// 优化空间 dp数组只用3格空间 记录与当前计算相关的前两个结果和当前结果
class Solution {public int rob(int[] nums) {int[] dp = new int[3];//初始化if(nums.length==1){return nums[0];}else if(nums.length==2){return Math.max(nums[1],nums[0]);}dp[0]=nums[0];dp[1]=Math.max(nums[1],nums[0]);for(int j=2;j<nums.length;j++){dp[2]=Math.max(dp[1], dp[0]+nums[j]);dp[0]=dp[1];dp[1]=dp[2];}return dp[2];}
}// 统一处理
class Solution {public int rob(int[] nums) {int[] dp = new int[3];for(int i=0;i<nums.length;i++){dp[2]=Math.max(dp[1], dp[0]+nums[i]);dp[0]=dp[1];        dp[1]=dp[2]; }return dp[2];}
}

213.打家劫舍II

教程视频:https://www.bilibili.com/video/BV1oM411B7xq
在这里插入图片描述
思路:
将环形问题转化为线性问题。本题可将环形问题分解为取第一个元素和不取第一个元素两种情况,考虑的长度为nums.length-1。即掐头和去尾,然后使用上一题的思路解决。

解法一:分别掐头和去尾,动态规划

class Solution {public int rob(int[] nums) {int len = nums.length;if (len == 1)return nums[0];int num0 = robLiner(nums, nums.length-1, 0);int num1 = robLiner(nums, nums.length-1, 1);return Math.max(num0, num1);}public int robLiner(int[] nums, int len,int startIndex) {int[] dp = new int[3];for(int i=startIndex;i<len+startIndex;i++){dp[2]=Math.max(dp[1], dp[0]+nums[i]);dp[0]=dp[1];        dp[1]=dp[2]; }return dp[2];}
}

337.打家劫舍III

教程视频:https://www.bilibili.com/video/BV1H24y1Q7sY
在这里插入图片描述
在这里插入图片描述

解法一:树的递归遍历+动态规划

思路:

  1. 对于树来说,当前节点能不能偷,需要依照其左子树根节点和右子树根节点是否被偷来判断,因此需要采用后序遍历(左右中)。
  2. 其次,为了保证计算出当以前节点的为根节点的二叉树能偷的最大金额,需要记录器左右子节点偷和不偷两种状态,因此递归函数的返回值是一个二维数组int[],其中mid[0]表示不偷的最大值,mid[1]表示偷的最大值。
  3. 最后考虑递归逻辑:
    如果是偷当前节点,那么左右孩子就不能偷,mid[1] = left[0]+right[0]+node.val;
    如果不偷当前节点,那么左右孩子就可以偷,至于到底偷不偷一定是选一个最大的,所以mid[0] = Math.max(left[0],left[1]) + Math.max(right[0],right[1]);
class Solution {public int rob(TreeNode root) {int[] res = traversal(root);return Math.max(res[0], res[1]);}public int[] traversal(TreeNode node){if(node==null)return new int[2];int[] left = traversal(node.left);int[] right = traversal(node.right);int[] mid = new int[2];mid[0] = Math.max(left[0],left[1])+Math.max(right[0],right[1]); //不偷nodemid[1] = left[0]+right[0]+node.val; //偷nodereturn mid;}
}

总结

对于环的问题,可以通过掐头,去尾转化成两个线性问题来解决。
树形dp要想清楚dp[i]需要想清楚保留什么状态,以及递归逻辑。


http://www.ppmy.cn/news/85185.html

相关文章

性能测试工程师必看——性能测试报告模板

目录 1. 测试概述 1.1 测试目标 1.2 指标和术语 2. 环境、工具 2.1 测试环境 2.2 测试工具 3. 测试方案 3.1 测试类型 3.2 业务模型 3.3 加密验签处理 3.4 压力梯度 4. 测试结果 4.1 聚合报告 4.2 系统吞吐量 4.3 资源占用率 5. 分析和建议 5.1 测试结论分析 …

网络安全就业有什么要求?一般人还真不行

前言 网络安全工程师又叫信息安全工程师。随着互联网发展和 IT 技术的普及&#xff0c;网络和 IT 已经日渐深入到日常生活和工作当中&#xff0c;社会信息化和信息网络化&#xff0c;突破了应用信息在时间和空间上的障碍&#xff0c;使信息的价值不断提高。但是与此同时&#…

【学习日记2023.5.22】 之 套餐模块完善

4. 功能模块完善之套餐模块 4.1 新增套餐 4.1.1 需求分析与设计 产品原型 后台系统中可以管理套餐信息&#xff0c;通过 新增功能来添加一个新的套餐&#xff0c;在添加套餐时需要添加套餐对应菜品的信息&#xff0c;并且需要上传套餐图片。 新增套餐原型&#xff1a; 当填…

【解决】前端项目编译卡在95% emitting HtmlWebpackPlugin很长时间

快速出击 原因 &#xff1a;问题原因最终定位在部分依赖版本不兼容&#xff0c;不适配。 解决方案 &#xff1a;删除node_modules文件夹&#xff0c;拷贝编译速度不慢人员电脑中的package-lock.json文件&#xff0c;然后执行npm install&#xff08;或者直接把node_modules打包…

GitLab Dogfooding 实践:Web API 模糊测试

本文来源&#xff1a;about.gitlab.com 作者&#xff1a;Eugene Lim&#xff0c;Mike Eddington 译者&#xff1a;极狐(GitLab) 市场部内容团队 在极狐GitLab/GitLab 内部&#xff0c;我们用 Dogfooding 文化来帮助更好地理解产品、解决痛点以及配置错误&#xff0c;构建一个更…

数据库学习2

加密函数 SELECT USER() FROM DUAL;--用户ip地址 SELECT DATABASE();--查看当前数据库名称 SELECT MD5(hsp) FROM DUAL;--为字符串算出32字符串&#xff0c;常用加密 SELECT LENGTH(MD5(hsp)) FROM DUAL; CREATE TABLE hsp_user( id INT, name VARCHAR(32) NOT NULL DEFAULT ,…

ES6:var 、const、let的使用和区别

前言 本文主要介绍了ES6中var、const、let的使用和区别 基本介绍 let let声明变量 const const :声明常量const声明的常量可以修改,但不能重新赋值 如&#xff1a;以下代码是正确的&#xff1a; //引用数据类型 const info {name:Candy }; info.nameJune;而下面的代码是…

AWS设备自定义身份认证

AWS设备自定义身份认证需要通过lambda服务实现&#xff0c;具体来说&#xff0c;首先需要创建一个lambda函数&#xff0c;在函数中实现具体的认证逻辑&#xff0c;然后Iot在调用授权方时&#xff0c;将触发lambda函数&#xff0c;返回认证结果。 1.输入参数说明 授权方在调用…