【LeetCode-337】打家劫舍III(动态规划)

目录

题目描述

解法1:动态规划

代码实现


题目链接

题目描述

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。

解法1:动态规划

这道题目算是树形dp的入门题目,因为是在树上进行状态转移,我们在讲解二叉树的时候说过递归三部曲,那么下面我以递归三部曲为框架,其中融合动规五部曲的内容来进行讲解

  1. 确定递归函数的参数和返回值

这里我们要求一个节点 偷与不偷的两个状态所得到的金钱,那么返回值就是一个长度为2的数组。

参数为当前节点,代码如下:

vector<int> robTree(TreeNode* cur) {

其实这里的返回数组就是dp数组。

所以dp数组(dp table)以及下标的含义:下标为0记录不偷该节点所得到的的最大金钱,下标为1记录偷该节点所得到的的最大金钱。

所以本题dp数组就是一个长度为2的数组!

那么有同学可能疑惑,长度为2的数组怎么标记树中每个节点的状态呢?

别忘了在递归的过程中,系统栈会保存每一层递归的参数

如果还不理解的话,就接着往下看,看到代码就理解了哈。

  1. 确定终止条件

在遍历的过程中,如果遇到空节点的话,很明显,无论偷还是不偷都是0,所以就返回

if (cur == NULL) return vector<int>{0, 0};

这也相当于dp数组的初始化

  1. 确定遍历顺序

首先明确的是使用后序遍历。 因为要通过递归函数的返回值来做下一步计算。

通过递归左节点,得到左节点偷与不偷的金钱。

通过递归右节点,得到右节点偷与不偷的金钱。

代码如下:

// 下标0:不偷,下标1:偷
vector<int> left = robTree(cur->left); // 左
vector<int> right = robTree(cur->right); // 右
// 中
  1. 确定单层递归的逻辑

如果是偷当前节点,那么左右孩子就不能偷,val1 = cur->val + left[0] + right[0]; (如果对下标含义不理解就再回顾一下dp数组的含义

如果不偷当前节点,那么左右孩子就可以偷,至于到底偷不偷一定是选一个最大的,所以:val2 = max(left[0], left[1]) + max(right[0], right[1]);

最后当前节点的状态就是{val2, val1}; 即:{不偷当前节点得到的最大金钱,偷当前节点得到的最大金钱}

代码如下:

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};

代码实现
class Solution {public int rob(TreeNode root) {if (root.left == null && root.right == null) return root.val;int[] dp = dfs(root);return Math.max(dp[0], dp[1]);}
​public int[] dfs(TreeNode root) {int[] leafArr = new int[2];if (root == null) return leafArr;int[] left = dfs(root.left);int[] right = dfs(root.right);
​int[] dp = new int[2];dp[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);dp[1] = root.val + left[0] + right[0];return dp;
​}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2804908.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

mysql-MVCC

一、基础概念 1. MVCC的含义 MVCC (Multiversion Concurrency Control)&#xff0c;即多版本并发控制技术&#xff0c;它是通过读取某个时间点的快照数据&#xff0c; 来降低并发事务冲突而引起的锁等待&#xff0c; 从而提高并发性能的一种机制. MVCC 的实现,是通过保存数据…

自定义股票池策略周报告---收益1.8,回撤0.7,提供实盘设置

综合交易模型已经交易了1个月了目前收益10&#xff0c;回测0.8&#xff0c;策略追求稳稳的幸福&#xff0c;细水流长&#xff0c;回测年化20&#xff0c;最大回撤8 链接自定义股票池策略周报告---收益1.8&#xff0c;回撤0.7&#xff0c;提供实盘设置 (qq.com) 实盘稳定运行2…

密评技术要求实施详解:每一步都关键

密评简介 密评定义&#xff1a;全称商用密码应用安全性评估, 是对采用商用密码技术、产品和服务集成建设的网络和信息系统密码应用的合规性、正确性、有效性进行评估的活动。 评测依据&#xff1a;GB/T 39786-2021《信息安全技术 信息系统密码应用基本要求》。 密评对象&…

Linux命令之ls命令

ls命令 ls命令的作用是列出目录下的内容&#xff0c;语法如下&#xff1a; ls [ -a -l -h ] [ Linux路径 ] 1、 -a -l -h 是可选的选项。 2、Linux路径是此命令可选的参数。 当不使用选项和参数&#xff0c;直接使用 ls 命令本体&#xff0c;表示&#xff1a;以平…

C++笔记:二叉搜索树(Binary Search Tree)

文章目录 二叉搜索树的概念二叉搜索树操作1. 框架搭建2. 遍历3. 查找迭代实现递归实现 4. 插入迭代实现递归实现 5. 删除迭代实现递归实现 6. 析构与销毁7. 拷贝构造与赋值重载 二叉搜索树的应用二叉搜索树的性能分析二叉搜索树模拟实现源码 二叉搜索树的概念 二叉搜索树又称二…

计算机网络面经-TCP三次握手一文说清

目录 说一下TCP的三次握手&#xff1f; 为什么要三次握手&#xff1f;两次行不行&#xff1f;四次呢&#xff1f; 为什么建立连接是三次握手&#xff0c;关闭连接确是四次挥手呢&#xff1f; TCP四次挥手的过程&#xff1f; 如果已经建立了连接&#xff0c;但是客户端突然出…

CentOS7 安装Python3.8

在 CentOS 7 上&#xff0c;按照以下步骤安装 Python 3.8&#xff1a; 添加EPEL仓库&#xff1a;首先安装 EPEL&#xff08;Extra Packages for Enterprise Linux&#xff09;仓库 sudo yum install epel-release安装Software Collections (SCL)仓库&#xff1a;随后&#xff0…

2015-2024年考研数学(一)真题练习和解析——选择题

各个大学已经陆陆续续开学了&#xff0c;备考2025年考研的同学也要紧锣密鼓地开始备考&#xff0c;尤其是三门公共课——政治、英语、数学&#xff0c;备考的时间和周期都比较长&#xff0c;每一门都是难啃的硬骨头。 在这三门公共课中&#xff0c;数学的灵活性是最大的&#x…

172基于matlab的MPPT智能算法

基于matlab的MPPT智能算法&#xff0c;通过细菌觅食进行优化。算法引入了趋向性操作&#xff0c;用以进行局部范围内的最优寻找&#xff1b;引入了复制操作&#xff0c;用以避免种群更新盲目随机性&#xff0c;加快了算法的收敛速度&#xff1b;引入了迁徙操作用以避免算法陷入…

TSL四次握手

HTTPS 常用的密钥交换算法有两种&#xff0c;分别是 RSA 和 ECDHE 算法。 其中&#xff0c;RSA 是比较传统的密钥交换算法&#xff0c;它不具备前向安全的性质&#xff0c;因此现在很少服务器使用的。而 ECDHE 算法具有前向安全&#xff0c;所以被广泛使用。 1. ECDHE算法 1.…

重看LeakCanary

LeakCanary是我很久之前看的东西了&#xff0c;我当时侯对它的印象就是它可以用来检测内存泄漏&#xff0c;具体原理就是将弱引用对象延迟个5s然后看是否被回收,如果没有被回收,那么就说明发生了内存泄漏,其他的也没有仔细地看 现在就详细地梳理一遍这个流程&#xff1a; 1.L…

Linux--自定义shell

shell shell就是操作系统提供给用户与操作系统进行交互的命令行界面。它可以理解为一个用户与操作系统之间的接口&#xff0c;用户可以通过输入命令来执行各种操作&#xff0c;如文件管理、进程控制、软件安装等。Shell还可以通过脚本编程实现自动化任务。 常见的Unix系统中使…

【Spring】SpringBoot 单元测试

目 录 一.什么是单元测试&#xff1f;二.单元测试有哪些好处&#xff1f;三.Spring Boot 单元测试使用单元测试的实现步骤 一.什么是单元测试&#xff1f; 单元测试&#xff08;unit testing&#xff09;&#xff0c;是指对软件中的最小可测试单元进行检查和验证的过程就叫单元…

爬虫知识--03

数据存mysql import requests from bs4 import BeautifulSoup import pymysql# 链接数据库pymysql conn pymysql.connect(userroot,password"JIAJIA",host127.0.0.1,databasecnblogs,port3306, ) cursor conn.cursor() cursor conn.cursor()# 爬数据 res request…

大模型+影像:智能手机“上春山”

这个春节假期&#xff0c;一首《上春山》火了。吃瓜群众热热闹闹学了一个假期的“春山学”&#xff0c;了解了抢占C位的各种技巧。 假期过去&#xff0c;开工大吉&#xff0c;手机行业开始抢占今年的C位。那么问题来了&#xff0c;今年智能手机最大的机会点在哪里&#xff1f;答…

Video generation models as world simulators-视频生成模型作为世界模拟器

原文地址&#xff1a;Video generation models as world simulators 我们探索在视频数据上进行大规模生成模型的训练。具体来说&#xff0c;我们联合训练文本条件扩散模型&#xff0c;同时处理不同持续时间、分辨率和长宽比的视频和图像。我们利用一个在视频和图像潜在编码的时…

Fiddler工具 — 21.Fiddler常用插件

Fiddler已有的功能已经够我们日常工作中使用了&#xff0c;为了更好的扩展Fiddler&#xff0c;Fiddler也是支持一些插件的安装&#xff0c;也支持用户自己开发插件并安装。 Fiddler插件下载地址&#xff1a;https://www.telerik.com/fiddler/add-ons 1、Traffic Differ Traf…

2023年的AI模型学习/部署/优化

可以的话&#xff0c;github上给点一个小心心&#xff0c;感谢观看。 LDC边缘检测的轻量级密集卷积神经网络&#xff1a; meiqisheng/LDC (github.com)https://github.com/meiqisheng/LDC segment-anything分割一切的图像分割算法模型&#xff1a; meiqisheng/segment-anyt…

pclpy KD-Tree K近邻搜索

pclpy KD-Tree K近邻搜索 一、算法原理1.KD-Tree 介绍2.原理 二、代码三、结果1.原点云2.k近邻点搜索后的点云 四、相关数据 一、算法原理 1.KD-Tree 介绍 kd 树或 k 维树是计算机科学中使用的一种数据结构&#xff0c;用于在具有 k 维的空间中组织一定数量的点。它是一个二叉…

SpringBoot-2.7.6基于SLF4J日志门面的日志框架切换

SpringBoot 没有强制性的日志记录依赖项,但 Commons Logging API 除外,它通常由 Spring Framework 的模块提供。 要使用 Logback,您需要将其包含在类路径中。 推荐的方法是您只需要通过启动器,这都取决于 . 对于 Web 应用程序 ,因为它可传递地依赖于日志记录启动器。 如果…