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

news2024/11/24 5:59:11

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.coloradmin.cn/o/1050110.html

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

相关文章

【Java 进阶篇】深入理解 SQL 聚合函数

在 SQL 数据库中&#xff0c;聚合函数是一组强大的工具&#xff0c;用于处理和分析数据。它们可以帮助您对数据进行统计、计算总和、平均值、最大值、最小值等操作。无论您是数据库开发者、数据分析师还是希望更好地了解 SQL 数据库的用户&#xff0c;了解聚合函数都是非常重要…

三个要点,掌握Spring Boot单元测试

单元测试是软件开发中不可或缺的重要环节&#xff0c;它用于验证软件中最小可测试单元的准确性。结合运用Spring Boot、JUnit、Mockito和分层架构&#xff0c;开发人员可以更便捷地编写可靠、可测试且高质量的单元测试代码&#xff0c;确保软件的正确性和质量。 一、介绍 本文…

(SAR)Sentinel-1影像自动下载

基于ASF网站提供的python代码&#xff0c;实现Sentinel-1影像的自动下载&#xff1b; 1、登录ASF网站 登录Sentinel-1影像ASF网站&#xff1a;https://search.asf.alaska.edu/&#xff1b; 点击网站最右侧Sign in图标&#xff0c;进行用户注册&#xff1b; 注册完用户之后&…

基于Vue+ELement实现增删改查案例与表单验证(附源码)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《ELement》。&#x1f3af;&#x1f3af; &#x1…

I2C外设

I2C的总结 I2C优点&#xff1a; 接口线少只有两根线&#xff0c;控制方式简单&#xff0c;通信速率较高&#xff1b; I2C 是飞利浦公司开发的两线式串行总线&#xff1b; I2C缺点&#xff1a; 硬件比较复杂&#xff0c;稳定性不太好&#xff0c;程序移植有点麻烦&#xff…

自定义v-resize指令并发布到NPM

自定义Vite库并发布到NPM 封装useResize 用于监听绑定元素的宽高变化&#xff0c;当元素宽高发生变化时触发回调并获取最新的宽高 新建项目 结合上面学到的 Hook 和 自定义指令封装一个监听元素宽高变化的指令&#xff0c;并发布到 npm 项目结构 useResize ├…

jQuery核心卷

目录 一.jQuery引用 二.jQuery语法 三.元素的属性 1.attr()方法 2.使用removeAttr()方法删除HTML元素的属性 3.使用text()方法设置HTML元素的文本内容 四.CSS元素控制 1.使用css()方法获取和设置css属性 2.与CSS类别有关的方法 3.获取和设置HTML元素的尺寸 4.获取和…

html 边缘融合加载

html 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>边缘融合加载</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}body {height: 100vh;padding-bottom: 80px;b…

No141.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

【STM32】IAP升级00 预备知识

IAP&#xff08;In Application Programming&#xff09;简介 Flash够大的情况下&#xff0c;上电后的程序通过修改 MSP 的方式&#xff0c;可以在一块Flash上存在多个功能差异的程序。 IAP是为了在执行正常功能前&#xff0c;为了升级功能&#xff0c;提前运行的一段程序。这…

26608-2011 工业用回收一氯甲烷 学习笔记

声明 本文是学习GB-T 26608-2011 工业用回收一氯甲烷. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了工业用回收一氯甲烷的要求、试验方法、检验规则及标志、包装、运输、贮存及安全。 本标准适用于副产回收生产的工业用一氯甲…

一些杂题(9.23)

八月赛 A. Extra Large Knapsack 我的思路 是否可行只要看所有异或在一起是否为0就可以了 可行的方案只要有一个在第一个包里&#xff0c;剩下的都在第二个包里就可以了 注意&#xff1a;n1的时候不可行&#xff0c;要特判 代码 #include<bits/stdc.h> using name…

手写Hystrix基本原理

本文已收录于专栏 《中间件合集》 目录 概念说明什么是HystrixHystrix解决的问题 提供服务工作流程代码实现HystrixSDKMyHystrixCommand注解MyHystrixProperty注解MyAspect注解解释器 发送请求端引入Hystrix的依赖调用代码 接收请求端执行效果发送请求端 总结提升 概念说明 什…

树莓集团又一力作,打造天府蜂巢成都直播产业园样板工程

树莓集团再次推出惊艳之作&#xff0c;以打造成都天府蜂巢直播产业园为目标。该基地将充分展现成都直播产业园的巨大潜力与无限魅力&#xff0c;成为一个真正的产业园样板工程。 强强联手 打造未来 成都天府蜂巢直播产业园位于成都科学城兴隆湖高新技术服务产业园内&#xff0…

毕业设计选题之Java+springboot线上蔬菜销售与配送系统(源码+调试+开题+lw)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…

基于Java的药品管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

国庆节难忘回家路:趣事、风景、反思

文章目录 前言趣事游记旅途风光在人气爆棚的小七孔古桥大七孔在喯珠泻玉的拉雅瀑布奇异罕见的水上森林在云雾缭绕的鸳鸯湖在天然地宫——天钟洞飞瀑流泉 反思人们在死亡之前自己会有预感吗&#xff1f;求索生死大问 中秋国庆的规划后记 前言 中秋国庆&#xff0c;双节汇在一起…

8、绩效看板与日清计划

6、片花关联长视频 7、脏话检测 内容仓的办公区挂着几台电视&#xff0c;显示每个人目前完成的工作量&#xff0c;这就是绩效看板&#xff08;如下图&#xff09;&#xff0c;每位来参观的领导&#xff0c;都觉得这个绩效看板的想法很有意思。绩效看板是制造业常用的管理方法&…

【数据结构初阶】六、线性表中的队列(链式结构实现队列)

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 【数据结构初阶】五、线性表中的栈&#xff08;顺序表实现栈&#xff09;_高高的胖子的博客-CSDN博客 1 . 队列&#xff08;Queue&#xff09; 队列的概念和结构&#xff1a; 队列…

基于Java的食堂管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统功能具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域…