DAY39|动态规划Part07|LeetCode:198.打家劫舍、213.打家劫舍II、337.打家劫舍III
目录
LeetCode:198.打家劫舍
基本思路
C++代码
LeetCode:213.打家劫舍II
基本思路
C++代码
LeetCode:337.打家劫舍III
基本思路
C++代码
LeetCode:198.打家劫舍
力扣题目链接
文字讲解:LeetCode:198.打家劫舍
视频讲解:动态规划,偷不偷这个房间呢?

基本思路
看到这个问题,很容易想到,需要对当前房屋偷与不偷两种状态进行判断,而这个状态和前一个房间和前两个房间是否被偷有很大的关系。
通过动规五部曲进行分析:
- 确定dp数组(dp table)以及下标的含义
dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]。
- 确定递推公式
首先决定dp[i]的因素就是第i房间偷还是不偷。而如果偷了第i个房间,那么其偷盗金额就和前两个房间有关;如果不偷第i个房间,显然dp[i]和前一个房间的金额相同。
因此容易推出递推公式为:dp[i] = max(dp[i-1],dp[i-2]+nums[i]);
- dp数组如何初始化
因为题目明确说明街道上存在一个以上的房屋,当街道上只有一个房屋时,我们直接返回nums[0],如果大于等于两个房屋时,我们令dp[0]为nums[0],令dp[1] = max(nums[0],nums[1]);
- 确定遍历顺序
dp[i] 是根据dp[i - 2] 和 dp[i - 1] 推导出来的,那么一定是从前到后遍历!
for (int i = 2; i < nums.size(); i++) {dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
}
- 举例推导dp数组
以示例二,输入[2,7,9,3,1]为例,红框dp[nums.size() - 1]为结果。

C++代码
class Solution {
public:int rob(vector<int>& nums) {if (nums.size() == 0) return 0;if (nums.size() == 1) return nums[0];vector<int> dp(nums.size());dp[0] = nums[0];dp[1] = max(nums[0], nums[1]);for (int i = 2; i < nums.size(); i++) {dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);}return dp[nums.size() - 1];}
};
LeetCode:213.打家劫舍II
力扣题目链接
文字讲解:LeetCode:213.打家劫舍II
视频讲解:动态规划,房间连成环了那还偷不偷呢?

基本思路
这个题目相对于上一个题目,不同点在于街道上的房子练成了一个圈,那么我们到底应不应该选择第一个房屋和最后一个房屋呢?
很容易想到可以分成三种情况:
- 情况一:考虑不包含首尾元素

- 情况二:考虑包含首元素,不包含尾元素

- 情况三:考虑包含尾元素,不包含首元素

而在情况二和情况三种我们提到可以考虑包含首尾元素,而不是一定包含,因此情况一的情形实际上是包含在情况二和情况三中的。
这个样子我们和容易和上个题目中的动规五部曲进行相同的分析了。无非就是进行判断的区间有所不同。
C++代码
// 注意注释中的情况二情况三,以及把198.打家劫舍的代码抽离出来了
class Solution {
public:int rob(vector<int>& nums) {if (nums.size() == 0) return 0;if (nums.size() == 1) return nums[0];int result1 = robRange(nums, 0, nums.size() - 2); // 情况二int result2 = robRange(nums, 1, nums.size() - 1); // 情况三return max(result1, result2);}// 198.打家劫舍的逻辑int robRange(vector<int>& nums, int start, int end) {if (end == start) return nums[start];vector<int> dp(nums.size());dp[start] = nums[start];dp[start + 1] = max(nums[start], nums[start + 1]);for (int i = start + 2; i <= end; i++) {dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);}return dp[end];}
};
LeetCode:337.打家劫舍III
力扣题目链接
文字讲解:LeetCode:337.打家劫舍III
视频讲解:动态规划,房间连成树了,偷不偷呢?

基本思路
这个题目结合了二叉树的相关知识,如果忘记了的同学可以重新回顾一下二叉树相关的知识和题目。这个题目当然也可以使用二叉树递归的方法进行求解,但是我们知道二叉树的时间复杂度远大于动态规划的时间复杂度,这就很容易导致出现超时的情况。
这道题目算是树形dp的入门题目,因为是在树上进行状态转移,我们在讲解二叉树的时候说过递归三部曲,那么下面我以递归三部曲为框架,其中融合动规五部曲的内容来进行讲解。
- 确定递归函数的参数和返回值
我们需要传入的是根节点,而返回的是所能偷到的最大金额,因此返回值是int类型。对于每个二叉树节点,我们需要求出对于当前节点偷与不偷两个状态。我们还需要设置一个函数,用来记录每个节点偷与不偷状态下所能获得的最大金额。传入的为当前节点的指针,返回为一个数组。
int rob(TreeNode* root)
vector<int> robTree(TreeNode* cur)
- 确定终止条件
对二叉树的所有节点进行遍历,当节点为空节点时,表示无论是否偷空节点,偷到的金额都为零,此时返回{0,0}。
if (cur == NULL) return vector<int>{0, 0};
- 确定遍历顺序
因为是否偷当前节点需要根据是否偷左右孩子获得的最大金额决定。因此需要先遍历左右孩子,在遍历中间节点,即遍历方式采用后序遍历。
- 确定单层递归的逻辑
遍历当前节点时,如果偷当前节点,那么就不能偷左右孩子,即取left[0]和right[0];如果不偷当前节点,那么就对左右节点是否偷盗的可以获得的金额求最大值。
vector<int> left = robTree(cur->left); // 左
vector<int> right = robTree(cur->right); // 右// 偷cur
int val1 = cur->val + left[0] + right[0];
// 不偷cur
int val2 = max(left[0], left[1]) + max(right[0], right[1]);
return {val2, val1};
- 举例推导dp数组
以示例1为例,dp数组状态如下:

最后头结点就是 取下标0 和 下标1的最大值就是偷得的最大金钱。
C++代码
class Solution {
public:int rob(TreeNode* root) {vector<int> result = robTree(root);return max(result[0], result[1]);}// 长度为2的数组,0:不偷,1:偷vector<int> robTree(TreeNode* cur) {if (cur == NULL) return vector<int>{0, 0};vector<int> left = robTree(cur->left);vector<int> right = robTree(cur->right);// 偷cur,那么就不能偷左右节点。int val1 = cur->val + left[0] + right[0];// 不偷cur,那么可以偷也可以不偷左右节点,则取较大的情况int val2 = max(left[0], left[1]) + max(right[0], right[1]);return {val2, val1};}
};相关文章:
DAY39|动态规划Part07|LeetCode:198.打家劫舍、213.打家劫舍II、337.打家劫舍III
目录 LeetCode:198.打家劫舍 基本思路 C代码 LeetCode:213.打家劫舍II 基本思路 C代码 LeetCode:337.打家劫舍III 基本思路 C代码 LeetCode:198.打家劫舍 力扣题目链接 文字讲解:LeetCode:198.打家劫舍 视频讲解:动态规划,偷不偷这个…...
MYSQL----------------sql 优化
优化 SQL 语句的一般步骤 1. 了解 SQL 的执行频率 SHOW STATUS LIKE Com_%;代码解释: SHOW STATUS LIKE Com_%;:此命令可以查看各种 SQL 语句的执行频率,例如 Com_select 表示 SELECT 语句的执行次数,Com_insert 表示 INSERT 语…...
深度学习中的正则化方法
最近看到了正则化的内容,发现自己对正则化的理解已经忘得差不多了,这里在整理一下,方便以后查阅。 深度学习中的正则化方法 1. L2 正则化(L2 Regularization)2. L1 正则化(L1 Regularization)3.…...
前端报告 2024:全新数据,深度解析未来趋势
温馨提示: 此报告为国际版全球报告,其中所涉及的技术应用、工具偏好、开发者习惯等情况反映的是全球前端开发领域的综合态势。由于国内外技术发展环境、行业生态以及企业需求等存在差异,可能有些内容并不完全契合国内的实际情况,请大家理性阅读,批判性地吸收其中的观点与信…...
计算机网络之---子网划分与IP地址
子网划分与IP地址的关系 在计算机网络中,子网划分(Subnetworking)是将一个网络划分为多个子网络的过程。通过子网划分,可以有效地管理和利用IP地址空间,提高网络的性能、安全性和管理效率。 子网划分的基本目的是通过…...
计算机网络 (31)运输层协议概念
一、概述 从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层。运输层的一个核心功能是提供从源端主机到目的端主机的可靠的、与实际使用的网络无关的信息传输。它向高层用…...
代码随想录算法训练营day28
代码随想录算法训练营 —day28 文章目录 代码随想录算法训练营前言一、122.买卖股票的最佳时机II二、55. 跳跃游戏三、跳跃游戏 II方法一方法二 1005. K 次取反后最大化的数组和总结 前言 今天是算法营的第28天,希望自己能够坚持下来! 今日任务&#x…...
建立时间和保持时间
建立时间 在时钟有效沿到来之前,数据必须维持一段时间保持不变,这段时间就是建立时间 Tsetup 1 基本概念 建立时间(Setup Time): 在 SystemVerilog 中,建立时间是指在时钟信号的有效边沿(例如…...
vue,router路由传值问题,引用官方推荐
参考贴https://blog.csdn.net/m0_57033755/article/details/129927829 根据官方文档的更新日志,建议使用state传值 官方文档更新日志 实际的console结果 传值 router.push({ name: KnowledgeDetail, state: { params } });接收值 const historyParams histor…...
AIDD-人工智能药物设计-AlphaFold系列:年终回顾,AlphaFold迄今为止的实际应用案例
AlphaFold系列:年终回顾,AlphaFold迄今为止的实际应用案例 01 引言 AlphaFold由 DeepMind 团队开发,最初在蛋白质结构预测竞赛 CASP 中惊艳亮相。随着 AlphaFold2 和后续版本的迭代进步,其精度和通用性不断提升,逐渐走…...
Scala语言的面向对象编程
Scala语言的面向对象编程 引言 在当今的软件开发中,面向对象编程(OOP)是一种非常强大且广泛使用的编程范式。Scala是一种现代编程语言,结合了面向对象编程和函数式编程的特性,非常适合用于大规模软件的开发。本文将介…...
MySQL学习记录1【DQL和DCL】
SQL学习记录 该笔记从DQL处开始记录 DQL之前值得注意的点 字段 BETWEEN min AND max 可以查询区间[min, max]的数值如果同一个字段需要满足多个OR条件,可以采取 字段 IN(数值1, 数值2, 数值3....)LIKE语句 字段 LIKE ___%%% 表示模糊匹配,_匹配一个字段…...
验证码转发漏洞
开发人员有时候会以数组的形式接收用户的手机号并遍历执行,这时就可以在注册或登录页面填写两个手机号并点击发送验证码,这两个手机号会同时收到相同验证码,可以用任意一个手机号登录或注册,即验证码转发漏洞。 1、burpsuite内置…...
使用 C++ 实现神经网络:从基础到高级优化
引言 在现代机器学习中,神经网络已经成为最重要的工具之一。虽然 Python 提供了诸如 TensorFlow、PyTorch 等强大的机器学习库,但如果你想深入理解神经网络的实现原理,或者出于某些性能、资源限制的考虑,使用 C 来实现神经网络会是…...
【WRF运行报错】总结WRF运行时报错及解决方案(持续更新)
目录 ./real.exe错误1:ERROR while reading namelist physics./wrf.exe错误1:FATAL CALLED FROM FILE: <stdin> LINE: 2419 Warning: too many input landuse types参考./real.exe 错误1:ERROR while reading namelist physics 执行./real.exe时,报错如下: taski…...
Kotlin语言的循环实现
Kotlin语言中的循环实现 Kotlin是一种现代的、跨平台的编程语言,广泛应用于Android开发、后端服务及多种其他软件开发领域。与Java类似,Kotlin也支持多种循环结构,包括for循环、while循环和do while循环。掌握这些循环结构是每个Kotlin开发者…...
基于CNN的人脸识别考勤管理系统实现
随着技术的不断进步,人脸识别技术已经在各行各业得到了广泛的应用,尤其在 考勤管理 上,它提供了更加智能、便捷、精准的解决方案。本篇博客将介绍如何基于 PyQt5 和 MySQL 实现一个 人脸识别考勤系统,并通过具体代码展示如何通过图…...
Android基于回调的事件处理
Android 中的回调机制:基于回调的事件处理详解 在 Android 开发中,回调(Callback)是一种常见的事件处理机制,主要用于异步操作和事件通知。与传统的基于监听器的事件处理相比,回调机制更加灵活、通用&…...
postgis和地理围栏
postgis postgis是pg数据库的一个插件,除原数据类型外(int varchar)、新增了空间数据类型(geography和geometry)。比如我们新建一张道路表road(字段有名称varchar、建设时间timestamp、地理位置geometry),可以将道路名字、建设时间存进去,同…...
《鸿蒙系统AI技术:筑牢复杂网络环境下的安全防线》
在当今数字化时代,复杂网络环境给智能系统带来了诸多安全挑战,而鸿蒙系统中的人工智能技术却展现出强大的安全保障能力,为用户在复杂网络环境中的安全保驾护航。 微内核架构:安全基石 鸿蒙系统采用微内核架构,将核心…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
