leetCode 213. 打家劫舍 II 动态规划 房间连成环怎么偷呢?

213. 打家劫舍 II - 力扣(LeetCode)

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。

给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。

示例 1:

输入:nums = [2,3,2]
输出:3
解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。

示例 2:

输入:nums = [1,2,3,1]
输出:4
解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。偷窃到的最高金额 = 1 + 3 = 4 。

示例 3:

输入:nums = [1,2,3]
输出:3

>>思路和分析

与leetCode 198.打家劫舍 动态规划是差不多的,唯一区别就是成环了。

对于一个数组,成环的话主要有如下几种情况:

  • 情况一,考虑不包含首尾元素

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

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

如果是线性数组的话,就是leetCode 198.打家劫舍 动态规划 。一旦连成环了,就开始犯懵了(=@__@=),不知道起点应该在哪里,终点应该在哪里。那么起点和终点我到底选不选呢?就会陷入这个泥潭里~

那么连成环的房间我们该从哪里思考呢?

在连成环的线性数组中,首元素和尾元素是相邻的。那么如果首元素和尾元素只能选一个,要不就选首元素要不就选尾元素,要不就是首尾元素都不选。此时可以化为3种情况。

  • 情况一,首尾都不考虑了,此时连成环对线性数组没有影响了。只考虑中间那段,此时就是一个线性数组,可以用线性数组的方式来解决它。可用leetCode 198.打家劫舍 的处理方式一样了
  • 情况二,考虑首元素,但不考虑尾元素。所以即使你的首尾元素相邻在一起对此无影响,此时就是一个线性数组,可以用线性数组的方式来解决它。可用leetCode 198.打家劫舍 的处理方式一样了。
  • 情况三,考虑尾元素,但不考虑首元素。所以即使你的首尾元素相邻在一起对此无影响,此时就是一个线性数组,可以用线性数组的方式来解决它。可用leetCode 198.打家劫舍 的处理方式一样了。

仔细分析情况二和情况三,是包含了情况一的。情况二是连首元素和中间部分都考虑了,那中间部分所得到的最优值,那么情况二也包含了。有友友可能就疑惑了(O_O)? 你情况二选头元素了呀,怎么能包含我情况一呢?这么想其实就是陷入了误区,因为这里是考虑的范围,是把首元素考虑进去了,没说一定要选首元素。选不选它,是由我们递推公式去决定的。这里考虑的范围,仅仅是遍历的范围,即遍历递推公式的范围。通俗讲就是这个范围就这么大,那么选不选首元素,是递推公式来决定的,没说一定要选首元素。所以说在这个范围内,考虑最优解是一定包含了情况一范围内的最优解。情况三也同理,它的范围内的最优解也一定包含了情况一范围内的最优解。

“考虑”二字,就很绝!例如情况三,虽然是考虑包含尾元素,但不一定要选尾部元素!对于情况三,取nums[1] nums[3] 就是最大的!!!而情况二 和 情况三 都包含了情况一了,所以只会考虑情况二 和 情况三 就可以了。

这是 leetCode 198.打家劫舍 动态规划 的核心代码

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(),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-1],dp[i-2] + nums[i]);}return dp[nums.size()-1];}
};// 时间复杂度: O(n)
// 空间复杂度: O(n)

我们把它抽离出来,就是robRange这个函数,我们可以传入nums,start,end这三个参数,可以实现截取数组的操作,以此实现情况二和情况三,然后将其各自得到的返回值中取一个最大值。这样就可以把这个环形问题化解为一个线性数组的问题。思路清晰~

// 注意注释中的情况二情况三,以及把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];}
};
  • 时间复杂度: O(n)
  • 空间复杂度: O(n)

#总结

成环之后,厘清“考虑房间” “偷房间”概念,然后厘清情况一、情况二、情况三的“考虑”范围,具体房间偷与不偷则交给递推公式去选择

考虑环形问题的时候,其实有的时候环形问题不利于我们的思考,会纠结起始位置在哪里,终止位置在哪里,选起始位置呢还是选末尾位置呢?那其实可以适当将这个环形给它展开,展开成一个线性的结构,接着单独再去考虑首元素和尾元素选还是不选,从而列举出三种情况。针对这三种情况再分析,情况二 和 情况 三 是包含了情况一的,那接下来就是一个线性数组问题了,和leetCode 198.打家劫舍 的处理方式一样了。

参考和推荐文章、视频

动态规划,房间连成环了那还偷不偷呢?| LeetCode:213.打家劫舍II_哔哩哔哩_bilibili

代码随想录 (programmercarl.com)

我的往期文章 

leetCode 198.打家劫舍 动态规划_呵呵哒( ̄▽ ̄)"的博客-CSDN博客

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

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

相关文章

websocket连接实例

websocket连接 此篇websocket是最简单的运用&#xff0c;虽然简单&#xff0c;但也是需要注意 还有其它方法货协议&#xff0c;比如socket.js等。今天时间不充裕虽然例子都写好了&#xff0c;下次更新websocket所有相关的东西。提前想了解的&#xff0c;可私信 前端 var webs…

Spring Cloud Stream Kafka(3.2.2版本)使用

问题 正在尝试只用Spring Cloud Stream Kafka。 步骤 配置 spring:cloud:function:definition: project2Building stream:kafka:binder:brokers: xxxx:9002configuration:enable.auto.commit: falsesession.timeout.ms: 30000max.poll.records: 30allow.auto.create.top…

PHP Web 开发基础

PHP是动态类型的Web开发的脚本语言&#xff0c;PHP以页面文件作为加载和运行的单元&#xff0c;PHP现在有了Composer作为开发包管理。 1.使用Composer管理依赖 自从.NET开发用了Nuget管理程序集依赖&#xff0c;我就再也离不开它了&#xff0c;幸亏Java中也有Maven管理jar包&…

如何定时备份使用Docker构建的MySQL容器中的数据库

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

PIE:1979-2018年中国气温数据产品(空间分辨率为0.1º)

简介 中国气温数据产品包含1979-2018年期间中国的近地表气温数据&#xff08;单位为摄氏度&#xff09;&#xff0c;时间分辨率为每日&#xff0c;空间分辨率为0.1。本产品集成了再分析数据&#xff08;ERA5、CMFD&#xff09;、遥感数据&#xff08;MODIS&#xff09;、原位数…

php eayswoole node axios crypto-js 实现大文件分片上传复盘

不啰嗦 直接上步骤 步骤1.开发环境配置 项目需要node.js 做前端支撑 官网下载地址&#xff1a; http://nodejs.cn/download/ 根据自己需要下载对应的版本,我下载的是windows系统64位的版本。 包下载好后 进行安装&#xff0c;安装步骤在此省略... 测试是否安装成功 …

蓝海彤翔亮相2023新疆网络文化节重点项目“新疆动漫节”

9月22日上午&#xff0c;2023新疆网络文化节重点项目“新疆动漫节”&#xff08;以下简称“2023新疆动漫节”&#xff09;在克拉玛依科学技术馆隆重开幕&#xff0c;蓝海彤翔作为国内知名的文化科技产业集团应邀参与此次活动&#xff0c;并在美好新疆e起向未来动漫展映区设置展…

C#生成自定义海报

安装包 SixLabors.ImageSharp.Drawing 2.0 需要的字体&#xff1a;宋体和微软雅黑 商用的需要授权如果商业使用可以使用方正书宋、方正黑体&#xff0c;他们可以免费商用 方正官网 代码 using SixLabors.Fonts; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Draw…

python切分字符串

在Python中&#xff0c;您可以使用不同的方法来切分字符串&#xff0c;具体取决于您的需求和字符串的结构。以下是一些常见的方法&#xff1a; 使用split()方法&#xff1a; split()方法允许您根据指定的分隔符将字符串切分成子字符串&#xff0c;并返回一个包含这些子字符串的…

使用SPY++查看窗口信息去排查客户端UI软件问题

目录 1、使用SPY查看窗口的信息 2、使用SPY查看某些软件UI窗口用什么UI组件实现的 2.1、查看海康视频监控客户端安装包程序 2.2、查看华为协同办公软件WeLink 2.3、查看字节协同办公软件飞书 2.4、查看最新版本的Chrome浏览器 2.5、查看小鱼易连视频会议客户端软件 2.6…

C/S架构学习之UDP服务器

UDP服务器的实现流程&#xff1a;一、创建用户数据报套接字&#xff08;socket函数&#xff09;&#xff1a;通信域选择IPV4网络协议、套接字类型选择数据报式&#xff1b; int sockfd socket(AF_INET,SOCK_DGRAM,0); 二、填充服务器的网络信息结构体&#xff1a;1.定义网络信…

Java初始化大量数据到Neo4j中(一)

背景&#xff1a;我们项目第一次部署图数据库&#xff0c;要求我们把现有的业务数据以及关系上线第一时间初始化到Neo4j中。开发环境数据量已经百万级别。生成环境数据量更多。 我刚开始开发的时候&#xff0c;由于对Neo4j的了解并没有很多&#xff0c;第一想到的是用代码通用组…

Mybatis 批量修改数据,,并判断非空数据插入

方法一&#xff1a; <update id"updateListPO"> <foreach collection"list" separator";" item"item">UPDATE project_quotation_item<SET>product_num #{item.productNum},product_price_total #{item.pr…

CIP或者EtherNET/IP中的PATH是什么含义?

目录 SegmentPATH举例 最近在学习EtherNET/IP&#xff0c;PATH不太明白&#xff0c;翻了翻规范&#xff0c;在这里记个笔记。下面的叙述可能是中英混合&#xff0c;有一些是规范中的原文我直接搬过来的。我翻译的不准确。 Segment PATH是CIP Segment中的一个分类。要了解PATH…

每日一题 322零钱兑换(完全背包)(灵神版本)

题目 与01背包的区别就是可以重复拿一件物品 零钱兑换 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff…

Dev C++安装与运行

参考: https://blog.csdn.net/Keven_11/article/details/126388791 https://www.cnblogs.com/-Wallace-/p/cpp-stl.html 2021年真题要求 2022年真题要求 河南省的考试环境 IDE环境 Dev C 安装 下载 安装 点击OK&#xff0c;选择我接受 修改安装路径为D盘d:\Program Fi…

MQTT协议是什么?快速了解MQTT协议在物联网中的应用

随着工业互联网的迅猛发展&#xff0c;工业设备数据采集和实时监控成为制造业提高生产效率和质量的重要手段。在物联网应用中&#xff0c;通信技术包括Wi-Fi、RFID、NFC、RS232、RS485、USB等&#xff0c;其中在物联网技术框架体系中所使用到的通讯协议主要有&#xff1a;AMQP、…

[ruby on rails] postgres sql explain 优化

一、查看执行计划 sql User.all.to_sql # 不会实际执行查询 puts ActiveRecord::Base.connection.explain(sql)# 会实际执行查询&#xff0c;再列出计划 User.all.explain# 会实际执行查询&#xff0c;再列出计划ActiveRecord::Base.connection.execute(EXPLAIN ANALYZE sql…

[论文笔记]P-tuning

引言 今天带来第四篇大模型微调的论文笔记GPT Understands, Too。 本篇工作提出的方法是P-tuning,使用可训练的连续提示嵌入,使GPT在NLU上表现比传统的全量微调的GPT更好的效果。P-tuning还提高了BERT在少样本和监督设定下的性能,大幅减少了提示工程的需求。 总体介绍 根…

Django(21):使用Celery任务框架

目录 Celery介绍Celery安装Celery使用项目文件和配置启动Celery编写任务调用异步任务查看任务执行状态及结果 设置定时和周期性任务配置文件添加任务Django Admin添加周期性任务启动任务调度器beat Flower监控任务执行状态Celery高级用法与注意事项给任务设置最大重试次数不同任…