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.xdnf.cn/news/145225.html

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

相关文章

学信息系统项目管理师第4版系列13_立项管理

1. 项目立项管理包括 1.1. 项目建议与立项申请 1.2. 项目可行性研究 1.2.1. 初步可行性研究 1.2.2. 详细可行性研究 1.2.2.1. 不可缺少 1.2.2.1.1. 【高21上选21】 1.2.3. 可以依据项目的规模和繁简程度合二为一 1.3. 项目评估与决策 2. 立项申请 2.1. 项目建议书 2…

针对数据中心机房散热问题仿真

在对于部分室内布局设计而言我们需要考虑到室内的空气流通问题&#xff0c;当然了对于数据中心机房而言&#xff0c;电子信息设备在运行过程中产生大量热&#xff0c;这些热量如果不能及时排除&#xff0c;将导致机柜或主机房内温度升高&#xff0c;过高的温度将使电子元器件性…

windows 修改hosts映射,可以ping通,但是无法通过http url 路径访问,出现 500 Internal Privoxy Error

问题描述 今天在学习nginx时&#xff0c;想在hosts配置一个nginx的域名映射&#xff0c;但是发现访问nginx服务的ip时可以访问通&#xff0c;在dos命令窗口ping配置的域名映射也可以ping通&#xff0c;但是一旦在浏览器通过http请求访问配置的hosts域名映射时却出现 500 Inter…

JOSEF约瑟DZJ-402 DZY-401导轨式中间继电器 触点形式 两转换 AC、DC220V

DZY(J)-400导轨式中间继电器 系列型号 DZY、DZJ-401 DZY、DZJ-402 DZY、DZJ-403 DZY、DZJ-404 DZY、DZJ-405 DZY、DZJ-406 DZY、DZJ-407 DZY、DZJ-408 DZY、DZJ-409 DZY、DZJ-410 DZY、DZJ-411 DZY、DZJ-412 DZY、DZJ-413 DZY、DZJ-414 DzY、DZJ-415 DZY、DZJ…

利用抽象工厂模式提升游戏开发的精度与灵活性

引言 大家好&#xff0c;我是亿元程序员&#xff0c;一位有着8年游戏行业经验的主程。 本系列是《和8年游戏主程一起学习设计模式》&#xff0c;让糟糕的代码在潜移默化中升华&#xff0c;欢迎大家关注分享收藏订阅。 在开发过程中&#xff0c;如何有效地管理各种游戏对象并…

PHP各种老版本下载方式

最近因工作需要&#xff0c;要下载PHP7.3的最新版本版本。 PHP官网上提供了各种老版本下载地址&#xff1a; https://windows.php.net/downloads/releases/archives/ 下载速度不稳定&#xff0c;时快时慢。 使用前&#xff0c;给下载留足时间。 貌似晚上速度快一些。

ORACLE 内存结构之系统全局区(SGA)

每个 Oracle 数据库实例都会在内存中分配一个很大的内存结构&#xff0c; 称为系统全局区(System Global Area), 这是一个大型的共享内存结构,每个Oracle进程都会访问它。 在Linux/Unix操作系统上,SGA是一个物理实体&#xff0c;使用操作系统命令能“看到它”。 它被操作系…

算法题系列8·买卖股票的最佳时机

目录 题目描述 实现 提交结果 题目描述 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。 设计一个算法来计算你所能获取的最大利润。…

mrctf2020_shellcode_revenge

mrctf2020_shellcode_revenge Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX disabled PIE: PIE enabled RWX: Has RWX segments64位&#xff0c;开了PIE和RELRO&#xff0c;看到RWX出来&#xff0c;就感觉是shellcode了…

什么是Promise链(Promise chaining)?它在异步编程中的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是 Promise 链&#xff1f;⭐ 异步编程中的作用⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、…

FreeRTOS入门教程(空闲任务和钩子函数及任务调度算法)

文章目录 前言一、空闲任务概念二、钩子函数概念三、任务调度算法四、任务调度算法实验1.实验代码2.是否抢占3.时间片是否轮转4.空闲任务让步 总结 前言 本篇文章将带大家学习一下什么是空闲任务以及钩子函数&#xff0c;以及学习FreeRTOS中的任务调度算法&#xff0c;了解在F…

基于风险的漏洞管理实现高效安全

通常&#xff0c;网络中存在很多漏洞&#xff0c;修补和修复它们是一个永无止境的过程。但总会有这样的问题&#xff1a;“我应该首先补救什么&#xff1f;如果在我发现另一个开放漏洞之前就被攻击者利用怎么办&#xff1f;” 如何才能避免自己陷入怨恨和悔恨的想法中&#x…

麒麟信安服务器操作系统V3.5.2重磅发布!

9月25日&#xff0c;麒麟信安基于openEuler 22.03 LTS SP1版本的商业发行版——麒麟信安服务器操作系统V3.5.2正式发布。 麒麟信安服务器操作系统V3定位于电力、金融、政务、能源、国防、工业等领域信息系统建设&#xff0c;以安全、稳定、高效为突破点&#xff0c;满足重要行…

2023-9-29 JZ33 二叉搜索树的后序遍历序列

题目链接&#xff1a;二叉搜索树的后序遍历序列 import java.util.*; public class Solution {int [] seq;public boolean VerifySquenceOfBST(int [] sequence) {if(sequence.length < 0) return false;this.seq sequence;return dfs(0, seq.length - 1);}public boolean …

【3】贪心算法-最优装载问题-加勒比海盗

算法背景 在北美洲东南部&#xff0c;有一片神秘的海域&#xff0c;那里碧海蓝天、阳光 明媚&#xff0c;这正是传说中海盗最活跃的加勒比海&#xff08;Caribbean Sea&#xff09;。 有一天&#xff0c;海盗们截获了一艘装满各种各样古董的货船&#xff0c;每一 件古董都价值连…

计算机图像处理-均值滤波

均值滤波 线性滤波器的原始数据与滤波结果是一种算术运算&#xff0c;即用加减乘除等运算实现&#xff0c;如均值滤波器&#xff08;模板内像素灰度值的平均值&#xff09;、高斯滤波器&#xff08;高斯加权平均值&#xff09;等。由于线性滤波器是算术运算&#xff0c;有固定…

嵌入式Linux应用开发-第十章LED模板总线设备驱动模型

嵌入式Linux应用开发-第十章LED模板总线设备驱动模型 第十章 LED模板驱动程序的改造&#xff1a;总线设备驱动模型10.1 原来的框架10.2 要实现的框架10.3 写代码10.3.1 注意事项10.3.2 实现 platform_device结构体10.3.3 实现 platform_driver结构体 10.4 课后作业 第十章 LED模…

HUAWEI悦盒ec6108v9c 如何刷成海纳思系统(家用低功耗服务器,使用Home Assistant服务)

环境&#xff1a; 1.HW悦盒ec6108v9c一套 2.16G U盘 3.格式化软件USB_format.exe 4.固件 mv100-mdmo1g-usb-flash.zip&#xff08;底层是Ubuntu 20.04系统&#xff09; 5.十字螺丝刀 6.翘片/薄铲子 7.有线网络环境 8.镊子/回形针 问题描述&#xff1a; 最近玩智能家居…

客户端负载均衡_负载均衡策略

以前的Ribbon有多种负载均衡策略 RandomRule - 随性而为 解释&#xff1a; 随机 RoundRobinRule - 按部就班 解释&#xff1a; 轮询 RetryRule - 卷土重来 解释&#xff1a; 先按照RoundRobinRule的策略获取服务&#xff0c;如果获取服务失败则在指定时间内会进行重试。 Weigh…

OpenHarmony自定义组件介绍

一、创建自定义组件 在ArkUI中&#xff0c;UI显示的内容均为组件&#xff0c;由框架直接提供的称为系统组件&#xff0c;由开发者定义的称为自定义组件。在进行 UI 界面开发时&#xff0c;通常不是简单的将系统组件进行组合使用&#xff0c;而是需要考虑代码可复用性、业务逻辑…