算法训练营 day51 动态规划 打家劫舍系列
算法训练营 day51 动态规划 打家劫舍系列
打家劫舍
198. 打家劫舍 - 力扣(LeetCode)
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
-
确定dp数组(dp table)以及下标的含义
dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]。
-
确定递推公式
决定dp[i]的因素就是第i房间偷还是不偷。
如果偷第i房间,那么dp[i] = dp[i - 2] + nums[i] ,即:第i-1房一定是不考虑的,找出 下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为dp[i-2] 加上第i房间偷到的钱。
如果不偷第i房间,那么dp[i] = dp[i - 1],即考 虑i-1房,(注意这里是考虑,并不是一定要偷i-1房,这是很多同学容易混淆的点)
然后dp[i]取最大值,即dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
-
dp数组如何初始化
从递推公式dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);可以看出,递推公式的基础就是dp[0] 和 dp[1]
从dp[i]的定义上来讲,dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1]);
-
定遍历顺序
dp[i] 是根据dp[i - 2] 和 dp[i - 1] 推导出来的,那么一定是从前到后遍历!
-
举例推导dp数组
以示例二,输入[2,7,9,3,1]为例。
红框dp[nums.size() - 1]为结果。
public static int rob(int[] nums) {int[] dp = new int[nums.length];if (nums.length<2){return nums[0];}dp[0] = nums[0];dp[1] = Math.max(dp[0],nums[1]);for (int i = 2;i < nums.length; i++) {dp[i] = Math.max(dp[i-1],dp[i-2]+nums[i]);}return dp[nums.length-1];}
打家劫舍II
213. 打家劫舍 II - 力扣(LeetCode)
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。
给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。
这道题目和198. 打家劫舍 是差不多的,唯一区别就是成环了。
对于一个数组,成环的话主要有如下三种情况:
- 情况一:考虑不包含首尾元素
- 情况二:考虑包含首元素,不包含尾元素
- 情况三:考虑包含尾元素,不包含首元素
注意我这里用的是"考虑",例如情况三,虽然是考虑包含尾元素,但不一定要选尾部元素! 对于情况三,取nums[1] 和 nums[3]就是最大的。
而情况二 和 情况三 都包含了情况一了,所以只考虑情况二和情况三就可以了。
分析到这里,本题其实比较简单了。 剩下的和198. 打家劫舍 就是一样的了。
class Solution {public int rob(int[] nums) {if (nums == null || nums.length == 0) return 0;if (nums.length == 1) return nums[0];return Math.max(robAction(nums,0, nums.length-2),robAction(nums,1, nums.length-1));}public int robAction(int[] nums, int start, int end) {if(start==end) return nums[start];int[] dp = new int[nums.length];dp[start] = nums[start];dp[start+1] = Math.max(nums[start],nums[start+1]);for (int i = start+2; i <=end ; i++) {dp[i] = Math.max(dp[i-1],dp[i-2]+nums[i]);}return dp[end];}
}
打家劫舍III
337. 打家劫舍 III - 力扣(LeetCode)
小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。
除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。
给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。
这道题目算是树形dp的入门题目,因为是在树上进行状态转移,我们在讲解二叉树的时候说过递归三部曲,那么下面我以递归三部曲为框架,其中融合动规五部曲的内容来进行讲解。
-
确定递归函数的参数和返回值
这里我们要求一个节点 偷与不偷的两个状态所得到的金钱,那么返回值就是一个长度为2的数组。
dp数组(dp table)以及下标的含义:下标为0记录不偷该节点所得到的的最大金钱,下标为1记录偷该节点所得到的的最大金钱。
所以本题dp数组就是一个长度为2的数组!
-
确定终止条件
在遍历的过程中,如果遇到空节点的话,很明显,无论偷还是不偷都是0,所以就返回
-
确定遍历顺序
首先明确的是使用后序遍历。 因为要通过递归函数的返回值来做下一步计算。
通过递归左节点,得到左节点偷与不偷的金钱。
通过递归右节点,得到右节点偷与不偷的金钱。
-
确定单层递归的逻辑
如果是偷当前节点,那么左右孩子就不能偷,val1 = cur.val + left[0] + right[0]; (如果对下标含义不理解就再回顾一下dp数组的含义)
如果不偷当前节点,那么左右孩子就可以偷,至于到底偷不偷一定是选一个最大的,所以:val2 = max(left[0], left[1]) + max(right[0], right[1]);
最后当前节点的状态就是{val2, val1}; 即:{不偷当前节点得到的最大金钱,偷当前节点得到的最大金钱}
-
举例推导dp数组
以示例1为例,dp数组状态如下:(注意用后序遍历的方式推导)
最后头结点就是 取下标0 和 下标1的最大值就是偷得的最大金钱。
class Solution {public int rob(TreeNode root) {int[] res = robTree(root);return Math.max(res[0],res[1]);}public int[] robTree(TreeNode root) {int[] res = new int[2];if (root==null) return new int[]{0,0};int[] left = robTree(root.left);int[] right = robTree(root.right);res[0] = Math.max(left[0],left[1])+Math.max(right[0],right[1]);res[1] = root.val +left[0]+right[0];return res;}
}
相关文章:

算法训练营 day51 动态规划 打家劫舍系列
算法训练营 day51 动态规划 打家劫舍系列 打家劫舍 198. 打家劫舍 - 力扣(LeetCode) 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#…...

【蓝桥集训】第六天——递归
作者:指针不指南吗 专栏:Acwing 蓝桥集训每日一题 🐾或许会很慢,但是不可以停下来🐾 文章目录1.树的遍历2.递归求阶乘3.求斐波那契数列1.树的遍历 一个二叉树,树中每个节点的权值互不相同。 现在给出它的后…...

react源码中的hooks
今天,让我们一起深入探究 React Hook 的实现方法,以便更好的理解它。但是,它的各种神奇特性的不足是,一旦出现问题,调试非常困难,这是由于它的背后是由复杂的堆栈追踪(stack trace)支…...

038.Solidity入门——25调用其他合约的方法
Solidity 提供了几种方式用于调用其他合约:方法描述直接调用使用 address.call 函数,可以向另一个合约发送消息并返回结果。低级调用使用 address.call 或 address.callcode 函数,可以执行一个外部合约中的代码。与直接调用不同,低…...

Revit项目浏览器的标准设置应用和快速视图样板?
一、Revit项目浏览器的标准设置应用 设计院阶段的BIM应用,主要是Revit出施工图方面,需要涉及到很多标准的制定方面的问题,而且这个标准不仅仅是一个命名标准,还有很多的符合本院的出图标准等等,本期就不做详细讨论&…...

安装MQTT Server遇到报错“cannot verify mosquitto.org‘s certificate”,该如何解决?
MQTT是基于发布/订阅的轻量级即时通讯协议,很适合用于低带宽、不稳定的网络中进行远程传感器和控制设备通讯等操作中。在我们的软件研发中,也经常使用MQTT协议进行消息通信等。今天来和大家分享一些关于在安装MQTT Server中遇到的疑难问题及解决思路。当…...

程序员如何向架构师转型?看完就明白该怎么做了
软件行业技术开发从业人员众多,但具备若干年开发经验的普通的开发人员往往面临个人发展的瓶颈,即如何从普通开发人员转型成高层次的系统架构师和技术管理人员。想成为一名架构师,应当具备全面的知识体系,需要进行系统的学习和实践…...

Flask入门(9):蓝图
目录9.蓝图9.1 概述9.2 蓝图项目结构结构1结构29.3 添加前缀9.4 静态文件9.5 模板9.6 构建 URLs9.蓝图 参考:http://www.pythondoc.com/flask/blueprints.html 9.1 概述 Flask 使用了 蓝图 的概念在一个应用或者跨应用中构建应用组件以及支持通用模式。 蓝图很好…...

跑步戴哪种耳机好,最适合运动跑步的蓝牙耳机
经常跑步使用的耳机,还是要选择佩戴着舒适以及牢固的运动耳机最为合适,在运动当中会遇到耳机掉落或者长时间佩戴耳道感到难受的现象发生,那么什么蓝牙耳机是最适合运动当中佩戴呢?下面这些耳机分享希望能够帮助大家。 1、南卡Run…...

微信小程序实现瀑布流布局
微信小程序实现瀑布流布局1、简单实例,纯图片后台返回图片高度https://blog.csdn.net/qq_45967222/article/details/1190318762、纯图片后台返回图片高度、通过wx.getImageInfo获取在线图片高度、按照奇数偶数来显示https://blog.csdn.net/baidu_35290582/article/d…...

2023最新网络工程师HCIA-Datacom“1000”道题库,光速刷题拿证
HCIA认证是华为认证体系的初级认证,可以说是网工进入IT行业的一张从业资格证! HCIA-Datacom考试覆盖数通基础知识 包括 TCP/IP 协议栈基础知识,OSPF 路由协议基本原理以及在华为路由器中的配置实现,以太网技术、生成树、VLAN 原…...

[蓝桥杯] 递归与递推习题训练
文章目录 一、递归实现指数型枚举 1、1 题目描述 1、2 题解关键思路与解答 二、递归实现排列型枚举 2、1 题目描述 2、2 题解关键思路与解答 三、递归实现组合型枚举 3、1 题目描述 3、2 题解关键思路与解答 四、带分数 4、1 题目描述 4、2 题解关键思路与解答 五、费解的开关…...

领航智能汽车信息安全新征程 | 云驰未来乔迁新址
2月20日,在北京朝阳百子湾东朝时代创意园,云驰未来迎来乔迁之喜,智能汽车和自动驾驶领域的行业领导、合作伙伴与客户、投资人及媒体嘉宾齐聚现场,共同见证云驰未来迈上新的发展征程。 作为中国智能网联汽车和自动驾驶信息安全行业…...

Kaldi语音识别技术(七) ----- 训练GMM
Kaldi语音识别技术(七) ----- GMM 文章目录Kaldi语音识别技术(七) ----- GMM训练GMMtrain_mono.sh 用于训练GMM训练GMM—生成文件训练GMM—final模型查看训练GMM—final.occs查看训练GMM—对齐信息查看训练GMM—fsts.*.gz查看训练GMM—tree决策树查看align_si.sh 用于对齐训练G…...

Java 集合基础
文章目录一、集合概念二、ArrayList1. 构造方法和添加方法2. 常用方法三、案例演示1. 存储字符串并遍历2. 存储学生对象并遍历3. 键盘录入学生对象并遍历一、集合概念 编程的时候如果要存储多个数据,使用长度固定的数组存储格式,不一定满足我们的需要&a…...

Day896.MySql的kill命令 -MySQL实战
MySql的kill命令 Hi,我是阿昌,今天学习记录的是关于MySql的kill命令的内容。 在 MySQL 中有两个 kill 命令: 一个是 kill query 线程 id,表示终止这个线程中正在执行的语句;一个是 kill connection 线程 id&#…...

L2-010 排座位
布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位。无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席。 输入格式࿱…...

C++的完美讲解,还不快来看看?
目录 简介: 创建C程序: Windows编译简介: Hello,C World! 简介: C融合了3中不同的编程传统:C语言代表的过程性传统、C在C语言基础上添加的类代表的面向对象语言的传统以及C模板支持的通用编程传统。一般来说,计算机语言…...

C语言学习_DAY_5_循环结构while和for语句【C语言学习笔记】
高质量博主,点个关注不迷路🌸🌸🌸! 目录 I. 案例引入 II. while语句 III. do while语句 IV. for语句 前言: 书接上回,判断结构已经解决,接下来是另一种很重要的结构:循环结构的实…...

JavaScript高级程序设计读书分享之4章——4.3垃圾回收
JavaScript高级程序设计(第4版)读书分享笔记记录 适用于刚入门前端的同志 4.3.3 性能 垃圾回收程序会周期性运行,如果内存中分配了很多变量,则可能造成性能损失,因此垃圾回收的 时间调度很重要。尤其是在内存有限的移动设备上,垃圾…...

Java线程的6 种状态
Java 线程的状态 Java线程有六种状态: 初始(NEW)、运行(RUNNABLE)、阻塞(BLOCKED)、 等待(WAITING)、超时等待(TIMED_WAITING)、终止(…...

5年测试在职经验之谈:3年手工测试、2年的自动化测试,从入门到不可自拔...
毕业3年了,学的是环境工程专业,毕业后零基础转行做软件测试。 已近从事测试行业8年了,自己也从事过3年的手工测试,从事期间越来越觉得如果一直在手工测试的道路上前进,并不会有很大的发展,所以通过自己的努…...

QHash-官翻
QHash 类 template <typename Key, typename T> class QHash QHash 类是一种模板类,提供基于哈希表的字典类结构。更多内容… 头文件:#include <QHash>qmake:QT core派生类:QMultiHash 所有成员列表,包括继承的成员废弃的成员 注意&…...

MYSQL 配置优化
max_connections 允许客户端并发连接的最大数量,默认值是151。 show status like %connections%; 设置参数值应大于Max_used_connections。如果使用连接池,可参考连接池的最大连接数和每个连接池的数量作为参考设置 innodb_buffe_pool_instances Inno…...

多 态
1多态的基本概念多态是C面向对象三大特性之一多态分为两类静态多态: 函数重载和运算符重载属于静态多态,复用函数名动态多态: 派生类和虚函数实现运行时多态静态多态和动态多态区别:静态多态的函数地址早绑定–--编译阶段确定函数地址动态多态的函数地址晚绑定–--运…...

Java集合
集合、数组都是对多个数据进行存储操作的结构,简称java容器 (此时的存储,主要指的是内存层面的存储,不涉及持久化的存储) 数组存储的特点: 一旦初始化,其长度就确定了。数组一旦定义好&#x…...

高校借力泛微,搭建一体化、流程化的内控管理平台
财政部《行政事业单位内部控制规范(试行)》中明确规定:行政事业单位内部控制是指通过制定制度、实施措施和执行程序,实现对行政事业单位经济活动风险的防范和管控,包括对其预算管理、收支管理、采购管理、资产管理、建…...

使用人工智能赚钱的方式,行业领域有哪些?
使用人工智能赚钱的方式,行业领域有哪些?不少于2000字。 一、人工智能的应用领域 1、金融服务:金融服务行业是人工智能应用的领域之一,它可以帮助银行、信用卡公司等金融机构实现快速、有效的贷款审批,以及客户分析、…...

【数组中重复的数字】-C语言-题解
原题链接:数组中重复的数字 一、描述: 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数…...

C++调用Python脚本进行18次循环操作后,脚本不执行
C调用Python脚本进行18次循环操作后,脚本不执行 现象: 发送端接收端 从第二张图中可以看出,python脚本卡在’[parkin_debug] 6’与’[parkin_debug] 7’之间 该测试经过多次反复测试,均在第18次循环执行时,出现上述问…...