面试算法89:房屋偷盗

题目

输入一个数组表示某条街道上的一排房屋内财产的数量。如果这条街道上相邻的两幢房屋被盗就会自动触发报警系统。请计算小偷在这条街道上最多能偷取到多少财产。例如,街道上5幢房屋内的财产用数组[2,3,4,5,3]表示,如果小偷到下标为0、2和4的房屋内盗窃,那么他能偷取到价值为9的财物,这是他在不触发报警系统的情况下能偷取到的最多的财物
在这里插入图片描述

分析

小偷在标号为i的房屋前有两个选择。一个选择是他进去偷东西。由于街道上有报警系统,因此他不能进入相邻的标号为i-1的房屋内偷东西,之前他最多能偷取的财物的最大值是f(i-2)。因此,小偷如果进入标号为i的房屋并盗窃,他最多能偷得f(i-2)+nums[i](nums是表示房屋内财物数量的数组)。另一个选择是小偷不进入标号为i的房屋,那么他可以进入标号为i-1的房屋内偷东西,因此此时他最多能偷取的财物的数量为f(i-1)。那么小偷在到达标号为i的房屋时他能偷取的财物的最大值就是两个选项的最大值,即f(i)=max(f(i-2)+nums[i],f(i-1)),这就是解决这个问题的状态转移方程。
上述状态转移方程有一个隐含条件,假设i大于或等于2。当i等于0时,f(0)是街道上只有标号为0的一幢房屋时小偷最多能偷得的财物的数量,此时他无所顾忌,直接进入标号为0的房屋偷东西,因此f(1)=nums[0];当i等于1时,f(1)是街道上只有标号为0和1的两幢房屋时小偷最多能偷得的财物的数量,因为街道上有报警系统,他只能到两幢房屋的其中一幢去偷东西,所以他应该选择到财物数量更多的房屋去偷东西,即f(1)=max(nums[0],nums[1])。

解: 带缓存的递归代码

public class Test {public static void main(String[] args) {int[] cost = {2, 3, 4, 5, 3};int result = rob(cost);System.out.println(result);}public static int rob(int[] nums) {if (nums.length == 0) {return 0;}int[] dp = new int[nums.length];Arrays.fill(dp, -1);helper(nums, nums.length - 1, dp);return dp[nums.length - 1];}private static void helper(int[] nums, int i, int[] dp) {if (i == 0) {dp[i] = nums[0];}else if (i == 1) {dp[i] = Math.max(nums[0], nums[1]);}else if (dp[i] < 0) {helper(nums, i - 2, dp);// 为什么传i-2,因为最后知道需要dp[i-2]的值helper(nums, i - 1, dp);// 为什么传i-1,因为最后知道需要dp[i-1]的值dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);}}
}

分析2:空间复杂度为O(n)的迭代代码

也可以换一种思路,即先求出f(0)和f(1)的值,然后用f(0)和f(1)的值求出f(2),用f(1)和f(2)的值求出f(3),以此类推,直至求出f(n-1)。这种自下而上的思路通常可以用一个for循环实现

public class Test {public static void main(String[] args) {int[] cost = {2, 3, 4, 5, 3};int result = rob(cost);System.out.println(result);}public static int rob(int[] nums) {if (nums.length == 0) {return 0;}int[] dp = new int[nums.length];dp[0] = nums[0];if (nums.length > 1) {dp[1] = Math.max(nums[0], nums[1]);}for (int i = 2; i < nums.length; i++) {dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);}return dp[nums.length - 1];}
}

分析3:空间复杂度为O(1)的迭代代码

如果仔细观察上述代码,就能发现计算“dp[i]”时只需要用到“dp[i-1]”和“dp[i-2]”这两个值,也就是说,只需要缓存两个值就足够了,并不需要一个长度为n的数组,因此,可以进一步优化代码的空间效率。

public class Test {public static void main(String[] args) {int[] cost = {2, 3, 4, 5, 3};int result = rob(cost);System.out.println(result);}public static int rob(int[] nums) {if (nums.length == 0) {return 0;}int[] dp = new int[2];dp[0] = nums[0];if (nums.length > 1) {dp[1] = Math.max(nums[0], nums[1]);}for (int i = 2; i < nums.length; i++) {dp[i % 2] = Math.max(dp[(i - 1) % 2], dp[(i - 2) % 2] + nums[i]);}return dp[(nums.length - 1) % 2];}
}

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

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

相关文章

http 503 错误

503错误是一种HTTP状态码&#xff0c;表示你请求的网站或服务暂时不可用&#xff0c;通常是因为服务器过载或维护&#xff0c;你可能会看到类似这样的提示&#xff1a;503 Service Unavailable、503 Service Temporarily Unavailable、HTTP Server Error 503、HTTP Error 503 I…

论文管理器

论文管理器 这个论文管理器仍然存在许多漏洞。目前&#xff0c;通过按照一些例行程序操作&#xff0c;它可以正常工作。我将在有时间的时候改进代码&#xff0c;提供详细说明&#xff0c;并添加新功能。当该管理器的代码进行优化后&#xff0c;我会上传到github上。 一个建立…

YACS(上海计算机学会竞赛平台)2023年12月月赛——移动复位

移动复位 内存限制: 256 Mb时间限制: 1000 ms 题目描述 二维平面上有一个点。该点最初所在的位置称之为起点。接下来&#xff0c;该点接受了一串命令&#xff0c;每个命令可以用一个大写字母表示&#xff1a; R 表示该点沿 X 轴坐标正方向移动了一个单位&#xff1b;L 表示…

Java商城 免 费 搭 建:鸿鹄云商实现多种商业模式,VR全景到SAAS,应有尽有

鸿鹄云商 b2b2c产品概述 【b2b2c平台】&#xff0c;以传统电商行业为基石&#xff0c;鸿鹄云商支持“商家入驻平台自营”多运营模式&#xff0c;积极打造“全新市场&#xff0c;全新 模式”企业级b2b2c电商平台&#xff0c;致力干助力各行/互联网创业腾飞并获取更多的收益。从消…

pod进阶:探针和容器钩子

探针* 容器钩子&#xff1a; poststart prestop pod的生命周期开始 Q&#xff1a;docker和k8s的重启策略对比 A&#xff1a; k8s的pod重启策略&#xff1a; Always&#xff1a;正常退出和非正常退出都重启&#xff08;deployment的yaml文件只能是Always。pod的yaml文件三…

【模拟量采集1.2】电阻信号采集

【模拟量采集1.2】电阻信号采集 1 怎么测&#xff1f;2 测输入电阻电压即转为测模拟电压值&#xff0c;这里需要考虑选用怎样的辅助电阻&#xff1f;3 实际电路分析3.1 在不考虑 VCC-5V 电压的纹波等情况时&#xff08;理想化此时输入的 VCC 就是稳定的 5V&#xff09;3.2 若考…

HT81698 内置升压双声道 相互p2p兼容 HT81696

HT81698内置升压的立体声D类音频功率放大器&#xff0c;其支持单节锂电、双节锂电串联、5V、12V等多种输入&#xff0c;升压后的电压提供给功放供电&#xff0c;功放支持双通道立体声BTL输出以及并联PBTL单声道输出; HT81698内置的升压电路&#xff0c;可通过FB脚设置升压值&a…

已解决‘ping‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。”的问题

已解决‘ping‘ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。”的问题 文章目录 问题介绍 问题分析 解决思路 解决方法 检查并修复环境变量 进入c:\windows\system32再ping 使用系统工具修复系统文件 Q1 - 问题介绍 当您尝试在Windows命令提示符下…

【Spring进阶系列丨第六篇】Spring的Bean管理(基于注解)

文章目录 一、说明二、用于创建对象的2.1、Component注解2.1.1、定义Bean2.1.2、主配置文件配置扫描注解2.1.3、测试2.1.4、Component注解总结 2.2、Controller注解2.3、Service注解2.4、Repository注解 三、用于注入数据的3.1、Autowired注解3.1.1、定义Bean3.1.2、主配置文件…

Linux学习(11)——进程的基本概念

目录 一、程序 1、什么是程序&#xff1f; 二、进程 1、什么是进程&#xff1f; 2、进程具有的特征 2.2进程&#xff0c;线程&#xff0c;协程 2.2.1 进程和线程的区别 2.2.2如何查看一个程序是多线程还是单线程 3、进程使用内存的问题 ①内存泄漏&#xff1a;Memory L…

GO语言笔记1-变量与基本数据类型

变量使用步骤 声明赋值使用 package main import "fmt" func main(){var age int //声明一个 int类型的变量叫ageage 18 //给变量用 赋值fmt.Println(age) //使用变量 输出变量的值 } 编译运行输出变量值 变量的四种使用方式 package main import "fmt&q…

【大数据】Spark学习笔记

初识Spark Spark和Hadoop HadoopSpark起源时间20052009起源地MapReduceUniversity of California Berkeley数据处理引擎BatchBatch编程模型MapReduceResilient distributed Datesets内存管理Disk BasedJVM Managed延迟高中吞吐量中高优化机制手动手动APILow levelhigh level流…

RFID技术在3C家电中的全方位应用

RFID技术在3C家电中的全方位应用 一、RFID技术简述 射频识别&#xff08;RFID&#xff09;技术是一种无线通信技术&#xff0c;已经在各行各业得到广泛应用。在3C家电领域&#xff0c;RFID技术的应用正在逐渐增加&#xff0c;为产品追溯、库存管理、防伪验证等方面提供了许多…

leetcode1944. 队列中可以看到的人数

Problem: 1944. 队列中可以看到的人数 文章目录 题目解题方法复杂度Code 题目 有 n 个人排成一个队列&#xff0c;从左到右 编号为 0 到 n - 1 。给你以一个整数数组 heights &#xff0c;每个整数 互不相同&#xff0c;heights[i] 表示第 i 个人的高度。 一个人能 看到 他右边…

JVM之对象创建

对象创建的流程 1.类加载检查 虚拟机遇到一条new指令时&#xff0c;首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有&#xff0c;那必须先执行相应的类加载过程。new指令对…

含科研思考六、关于【图神经网络】的一些要点 | 图神经网络节点表示学习研究:选题参考、问题探讨 | 图神经网络多模态 | 异构图神经网络

我们抬头便看到星光,星星却穿越了万年. 🎯作者主页: 追光者♂🔥 🌸个人简介: 📝[1] CSDN 博客专家📝 🏆[2] 人工智能领域优质创作者🏆 🌟[3] 2023年城市之星领跑者TOP1(哈尔滨)🌿 🌿[4] 2022年度博客之星人工智能领域TOP4🌟 🏅

Docker-Compose部署Redis(v7.2)主从模式

文章目录 一、前提准备1. redis配置文件2. 下载redis镜像3. 文件夹结构 二、docker-compose三、主从配置1.主节点配置文件 环境 docker desktop for windows 4.23.0redis 7.2 一、前提准备 1. redis配置文件 因为Redis 7.2 docker镜像里面没有配置文件&#xff0c;所以需要…

Color Control

设计一个优秀的用户界面是一项艰巨的任务。特别是如果你想改变UI的颜色,调整所有元素可能需要花费大量时间。Color Control可以帮助你!在检查器中以可视化的方式将你的项目颜色定义为资源。Color Control为你提供了组件,当你编辑它们时,它们会自动更新你的UI元素。 颜色控制…

Oracle-游标

简介 游标即cursor&#xff0c;是一种用于遍历结果集的数据类型。它是一个指向结果集的指针&#xff0c;可以用于遍历结果集中的每一行数据&#xff0c;但是一次只能指向一行。游标通常用于存储过程和函数中&#xff0c;以便在处理结果集时能够逐行处理数据。 语法 /* 游标:(…

花了一小时,拿python手搓了一个考研背单词软件

听说没有好用的电脑端背单词软件&#xff1f;只好麻烦一下&#xff0c;花了一小时&#xff0c;拿python手搓了一个考研背单词软件。 代码已经开源在我的github上&#xff0c;欢迎大家STAR&#xff01; 其中&#xff0c;数据是存放在sqlite中&#xff0c;形近词跳转是根据jaro …