165、【动态规划】leetcode ——337. 打家劫舍 III:记忆化递归+动态规划(C++版本)

news2024/9/22 3:56:16

题目描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
原题链接:337. 打家劫舍 III

解题思路

(1)记忆化递归

采用后序遍历的方式,设置一个unordered_map型Hash表record,记录每个结点的情况。当遍历到该节点时,判定之前是否遍历过,如果遍历过,直接返回record中记录结果,如果没有遍历过继续探查。因为,要找的只有两种情况,一个是不偷该节点,则向下一个结点去探查另一个是偷该节点,则不偷下一个结点,向下下个结点去探查。最终,找到二者之间的最大值,返回。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    unordered_map<TreeNode*, int> record;
    int rob(TreeNode* root) {
        if(!root)                               return 0;
        if(!root->left && !root->right)         return root->val;
        // 如果当前位置已被记录过,则直接返回结果
        if(record[root] != 0)                   return record[root];
        // val1:不偷当前结点,val2:偷当前结点
        int val1 = 0, val2 = root->val;
        val1 = rob(root->left) + rob(root->right);
        if(root->left)          val2 += rob(root->left->left) + rob(root->left->right);
        if(root->right)         val2 += rob(root->right->left) + rob(root->right->right);
        record[root] = max(val1, val2);

        return max(val1, val2);
    }
};

(2)动态规划

  • 递归三步曲 + 动态规划五步曲

(1)确定递归函数参数和返回值:

vector<int> robTree(TreeNode* root)

参数为root,返回值为长度为2的dp数组,下标0表示不偷root的结果,下标1表示偷root的结果。

(2)确定终止条件:

if(!root)           return vector<int>{0, 0};

当遍历到空节点时,返回{0, 0}

(3)确定遍历顺序:

因为dp数组是从小到大,大的要基于小的结果去进行操作。所以,需要使用后序遍历的方式,左右中的顺序遍历。底层的结果返回给上一层,上一层处理完后再返回给其上一层。

(4)确定单层递归逻辑:
对左右遍历完后,用val1记录不偷时的情况,找出偷下一个结点值更大,还是不偷下一个结点值更大。用val2记录偷时的情况,当前结点加上不偷下一个结点时的情况。

(5)举例:
image.png

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:    
    // 每次返回一个长度为2的数组,下标0:不偷的结果,下标1:偷的结果,取二者中的最大值
    vector<int> robTree(TreeNode* root) {
        if(!root)           return vector<int>{0, 0};
        vector<int> left = robTree(root->left);
        vector<int> right = robTree(root->right);
        // val1:不偷,val2:偷        
        int val1 = max(left[0], left[1]) + max(right[0], right[1]);
        int val2 = root->val + left[0] + right[0];
        
        return {val1, val2};
    }
    int rob(TreeNode* root) {
        vector<int> res = robTree(root);
        return max(res[0], res[1]);
    }
};

参考文章:337. 打家劫舍 III

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

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

相关文章

docker基本内容简单复习

文章目录一、docker简介docker镜像镜像的优化二、docker网络三、docker数据卷一、docker简介 docker是管理容器的引擎&#xff0c;docker为应用打包、部署平台&#xff0c;而非单纯的虚拟化技术 docker镜像 docker镜像是分层结构&#xff1b;共享宿主机kernel&#xff1b;同一…

【网安神器篇】——系统指纹探测工具finger

作者名&#xff1a;白昼安全主页面链接&#xff1a; 主页传送门创作初心&#xff1a; 以后赚大钱座右铭&#xff1a; 不要让时代的悲哀成为你的悲哀专研方向&#xff1a; web安全&#xff0c;后渗透技术每日鸡汤&#xff1a; 我不想停下&#xff0c;因为这次出发的感觉太好了一…

【双指针问题】977. 有序数组的平方

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…

Python快速上手系列--日志模块--详解篇

前言本篇主要说说日志模块&#xff0c;在写自动化测试框架的时候我们就需要用到这个模块了&#xff0c;方便我们快速的定位错误&#xff0c;了解软件的运行情况&#xff0c;更加顺畅的调试程序。为什么要用到日志模块&#xff0c;直接print不就好了&#xff01;那得写多少print…

【Linux】进程的概念及操作进程

目录1.什么是进程2.描述进程 - PCB3.进程的具体操作3.1进程的属性与文件属性的关系3.2查看进程准备工作使用指令查找对应进程&#xff1a;在文件中查看进程3.3关闭进程ctrlckill3.4进程的一些特性3.5通过系统调用获取进程标识符3.6通过系统调用创建子进程1.什么是进程 背景&am…

工程师手册:电源设计中的电容选用规则

摘要 电源往往是我们在电路设计过程中最容易忽略的环节。作为一款优秀的设计&#xff0c;电源设计应当是很重要的&#xff0c;它很大程度影响了整个系统的性能和成本。电源设计中的电容使用&#xff0c;往往又是电源设计中最容易被忽略的地方。一、电源设计中电容的工作原理 在…

前段时间公司招人,面了一个要20K的,一问自动化只会点皮毛···

前段时间公司要招2个自动化测试&#xff0c;同事面了几十个候选人&#xff0c;发现了一个很奇怪的现象&#xff0c;面试的时候&#xff0c;如果问的是框架api、脚本编写这些问题&#xff0c;基本上个个都能对答如流&#xff0c;等问到实际项目的时候&#xff0c;类似“怎么从0开…

vue+elementUI 实现设置还款日字母弹窗组件

1、业务背景 还款业务&#xff0c;设置每月还款日&#xff0c;选每月几号扣款&#xff0c;不需要29、30、31&#xff0c;因为不是每个月都有这三天的 2、预期效果图 3、代码实现 3.1 初始化vue项目 地址&#xff1a;https://cn.vuejs.org/guide/introduction.html 3.2 在项…

KMS钥匙管理系统产品分析

背景&#xff1a; 人造成的不可控因素很多 以前拿公司钥匙的时候要先进行纸质登记&#xff0c;还钥匙的的时候也要进行纸质统计&#xff0c; 这个过程中有很多不可控的因素&#xff0c;如果没有登记怎么办&#xff1f;人把钥匙丢了怎么办呢&#xff1f; 产品设计 引入机器&am…

UDP网络编程

UDP和TCP 前几节我们提到了计算机网络编程中的TCP编程&#xff0c;TCP和UDP都是计算机机网络通信的传输层中的传输协议&#xff0c;今天我们来学习计算机网络编程中的基于UDP传输协议的网络编程 首先我们要了解TCP和UDP的区别 它们是同属于计算机网络传输层的传输协议 TCP&…

LeetCode24两两交换链表中的节点 带有输入和输出的完整程序

题目&#xff1a;给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4] 输出…

CSAPP学习笔记——虚拟内存(一)

虚拟内存的能力 它将主存看成是一个存储在地址空间的高速缓存&#xff0c;在主存中只保存活动区域&#xff0c;并更具需要在磁盘和主存之间来回传送数据&#xff0c;通过这种方式来高效使用主存&#xff08;DRAM&#xff09;它为每个进程提供了一致的地址空间&#xff0c;从而…

python虚拟环境与环境变量

一、环境变量 1.环境变量 在命令行下&#xff0c;使用可执行文件&#xff0c;需要来到可执行文件的路径下执行 如果在任意路径下执行可执行文件&#xff0c;能够有响应&#xff0c;就需要在环境变量配置 2.设置环境变量 用户变量&#xff1a;当前用户登录到系统&#xff0c;…

【LeetCode】剑指 Offer 07. 重建二叉树 p62 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/zhong-jian-er-cha-shu-lcof/ 1. 题目介绍&#xff08;07. 重建二叉树&#xff09; 输入某二叉树的前序遍历和中序遍历的结果&#xff0c;请构建该二叉树并返回其根节点。 假设输入的前序遍历和中序遍历的结果中都不含重复的…

回溯算法问题汇总

文章目录模版一. 组合问题77. 组合216.组合总和III17.电话号码的字母组合39. 组合总和40.组合总和II131.分割回文串93.复原IP地址78.子集90.子集II491.递增子序列46.全排列47.全排列 II332.重新安排行程51. N皇后37. 解数独模版 void backtracking(参数) {if (终止条件) {存放…

Webpack(通俗易懂介绍)

主题&#xff1a;为什么需要webpack&#xff0c;用来干什么&#xff1f; 前言 例如&#xff1a;前端不断的技术更新迭代&#xff0c;为了浏览器更好的兼容到以及项目更好的开发&#xff0c;所有才有需要Webpack来打包代码&#xff0c;本文介绍下&#xff0c;Webpack的定义。 …

无FTTR不千兆,华为星光F30让家中不再有“隐秘的角落”

“恒有二者&#xff0c;余畏敬焉。位我上者&#xff0c;灿烂星空&#xff1b;道德律令&#xff0c;在我心中。”康德《实践理性批判》中&#xff0c;将人对外部世界的探索精神&#xff0c;抽象成了对无尽星空的追逐。以前&#xff0c;光为我们照亮现实世界。现在&#xff0c;人…

vue使用axios发送post请求携带json body参数,后端使用@RequestBody进行接收

前言 最近在做自己项目中&#xff0c;做一个非常简单的新增用户场景&#xff0c;但是使用原生axios发送post请求的时候&#xff0c;还是踩了不少坑的。 唉&#xff0c;说多了都是泪&#xff0c;小小一个新增业务&#xff0c;在自己前后端一起开发的时候&#xff0c;硬是搞了好…

使用QQ聊天机器人上传每日健康日报【Nonebot插件教程】

文章目录前言一、需求分析1.功能需求2.技术需求二、流程分析1.分析请求过程2.分析代码编写过程四、代码编写前言 作为2020级入学的大学生&#xff0c;在疫情的笼罩下步入了大学的校门&#xff0c;到校第一件事就是接到了每日进行健康日报身体情况上报的通知&#xff0c;每日醒…

08 OpenCV腐蚀、膨胀与形态学运算

1 腐蚀 腐蚀操作是一种形态学操作&#xff0c;它用于缩小二值图像中的对象&#xff0c;并去除图像中的噪声和细节。其基本原理是将图像中的每个像素与内核进行比较&#xff0c;如果内核覆盖的区域内所有像素值都为非零值&#xff0c;则该像素保持不变&#xff1b;否则&#xf…