代码随想Day48 | 198.打家劫舍、213.打家劫舍II、337.打家劫舍III

news/2025/1/15 18:19:19/

198.打家劫舍  

这一题用动态规划五步:

1. dp[i]:到位置i,获得的最大金额;

2. 递推:当前位置偷:dp[i-2]+nums[i];当前位置不偷:dp[i-1];dp[i]=max(偷,不偷);

3. 初始化:dp[0]=num[0], dp[1] = max(num[0],num[1]);

4. 遍历顺序:从前到后

详细代码:

class Solution {
public:int rob(vector<int>& nums) {//dp[i]:到达i位置时,最大的金额if(nums.size()==1) return nums[0];if(nums.size()==2) return max(nums[0],nums[1]);vector<int>dp(nums.size(),0);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];}
};

213.打家劫舍II  

打家劫舍2,我的思路就是基于原有的打家劫舍,把数组分为两个线性,一个只考虑头,一个只考虑尾,进行一遍从头开始到倒数第二个的遍历和另一边从第二个元素开始到最后的遍历,最后再取两个中的最大值,详细代码如下:

class Solution {
public:int rob(vector<int>& nums) {//首尾不能同时偷,所以分两遍进行递推if(nums.size()==1) return nums[0];if(nums.size()==2) return max(nums[0],nums[1]);if(nums.size()==3) return max(nums[0],max(nums[1],nums[2]));vector<int>dp1(nums.size(),0);vector<int>dp2(nums.size(),0);dp1[0]=nums[0],dp1[1]=max(nums[0],nums[1]);for(int i=2;i<nums.size()-1;i++){dp1[i]=max(dp1[i-2]+nums[i],dp1[i-1]);}dp2[1]=nums[1],dp2[2]=max(nums[1],nums[2]);for(int i=3;i<nums.size();i++){dp2[i]=max(dp2[i-2]+nums[i],dp2[i-1]);}return max(dp1[nums.size()-2],dp2[nums.size()-1]);}
};

337.打家劫舍III  

这道题目是树形dp的思路,需要把二叉树遍历和dp结合起来:

首先从递归开始思考:(需要用后序来返回节点的最大值)

参数:返回值应该是一个数组,分别是当前节点不偷和偷的最大值;传入参数则是树节点;

结束条件:当遍历到null节点,则最大值为0;

处理逻辑:先左右递归,然后再处理当前节点的逻辑。

dp的思路:

dp[0] 当前不偷节点的最大值,dp[1]:当前偷节点的最大值

递推公式:

当前偷的最大值应该等于当前值加左孩子的不偷最大值和有孩子的不偷最大值:

dp[0] = cur->val+leftdp[0]+rightdp[0];

当前不偷的最大值应该等于左孩子的偷取最大值加右孩子的偷取最大值:

dp[1]=max(leftdp[0],leftdp[1])+max(rightdp[0],rightdp[1]);

详细代码如下:

/*** 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:vector<int> dfs(TreeNode*root){if(root==nullptr) return vector<int>{0,0};//结束条件vector<int>l = dfs(root->left);vector<int>r = dfs(root->right);int val1 = root->val+l[0]+r[0];//当前节点偷int val2 = max(l[0],l[1])+max(r[0],r[1]); //当前不偷return vector<int>{val2,val1};}int rob(TreeNode* root) {vector<int>dp(2,0);dp = dfs(root);//0 不偷 1:偷return max(dp[0],dp[1]);}
};


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

相关文章

03-C++ 类和对象

类和对象 1. 概述 1.1 对象 真实存在的事物1.2 类 多个对象抽取其共同特点形成的概念静态特征提取出来的概念称为成员变量&#xff0c;又名属性 动态特征提取出来的概念称为成员函数&#xff0c;又名方法1.3 类与对象的关系 在代码中先有类后有对象 一个类可以有多个对象 …

遇到DDOS怎么办,盾真的可以抗攻击吗

网络在以难以想象的速度发展&#xff0c;黑客们针对网络漏洞发起的攻击也从未停止&#xff0c;但复杂的网络环境让网络安全的维护更为艰难&#xff0c;如果游戏公司没有做好防御措施&#xff0c;黑客发起攻击只是时间问题。在网络攻击愈加多元化的今天&#xff0c;游戏行业可以…

Fortofy扫描安全漏洞解决——Unreleased Resource: Streams未释放资源漏洞

问题描述&#xff1a; 大部分 Unreleased Resource 问题只会导致一般的软件可靠性问题&#xff0c;但如果攻击者能够故意触发资源泄漏&#xff0c;该攻击者就有可能通过耗尽资源池的方式发起 denial of service 攻击。 问题代码&#xff1a; FileInputStream inputStream new…

Ai企业系统源码 Ai企联系统源码 商用去授权 支持文心 星火 GPT4等等20多种接口

智思Ai系统2.4.9版本去授权&#xff08;可商用&#xff09;支持市面上所有版本的接口例如&#xff1a;文心、星火、GPT4等等20多种接口&#xff01;代过审AI小程序类目&#xff01;&#xff01;&#xff01; 安装步骤&#xff1a; 1、在宝塔新建个站点&#xff0c;php版本使用…

Linux工具之vi/vim

文章目录 vi/vimvim的基本概念vim的基本操作命令模式命令集末行模式命令集vim的配置配置文件的位置常用配置选项 vi/vim 简单来说&#xff0c;vi和vim基本上都是所有Linux系统自带的编辑器&#xff0c;但是我们不排除在未来的某些极端条件下&#xff0c;需要利用vi/vim进行代码…

财务数据智能化:用AI工具高效制作财务分析PPT报告

Step1: 文章内容提取 WPS AI 直接打开文件&#xff0c;在AI对话框里输入下面指令&#xff1a; 假设你是财务总监&#xff0c;公司考虑与茅台进行业务合作、投资或收购&#xff0c;请整合下面茅台2021年和2022年的财务报告信息。整理有关茅台财务状况和潜在投资回报的信息&…

Global Mapper SDK 19 中文开发文档(八)

7.2.8 GM_DBUtil &#xff08;1&#xff09;声明 public static class GM_DBUtil &#xff08;2&#xff09;方法 方法描述DBGetTableList获取指定空间数据库中的表列表DBIsDatabaseFile指示输入文件是否为数据库&#xff08;Esri地理数据库、Spatialite等&#xff09;DBMa…

用Disruptor框架实现生产者-消费者模式

ConcurrentLinkedQueue队列的秘诀就在于大量使用了无锁CAS操作。 现成的Disruptor框架实现CAS进行编程。 无锁的缓存框架&#xff1a;Disruptor 它使用无锁的方式实现了一个环形队列&#xff0c;非常适合实现生产者-消费者模式&#xff0c; 比如事件和消息的发布。如果队列是环…