当前位置: 首页 > news >正文

面试热题(打家窃舍)

一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响小偷偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

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

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

       如上图,每个房间放的金子都不同,有多有少,两个房间之间有警报相连,如果同时偷取相连的两个房子,警报就会发出,你就要去蹲局子,那么如何做一个聪明的小偷,在不触发警报的情况下偷取的金额是最大的,接下来,让我们替小偷想一个方案,如何去偷?

我们可以从后往前考虑,假如我们偷取最后一间房间

 我们是不是不可以偷取倒数第二间房间,可供的选择就是在倒数第二间之后随便选一家进行偷取

       为了利益最大化,我们是不是应该偷取的是前n-2间房子的最大金额数+最后一间房子的最大金额数就是我们当前可以偷取的最大金额数呢?NONONO,我们还有一种不偷取最后一间房子的情况,偷取n-2房间的情况

 我们通过上述的推导就可以将动态转移方程写出来

 dp[i]=Math.max(dp[i-1],nums[i]+dp[i-2]);

我们设置的dp数组的语意是dp[i]是,偷取第i家的最大金额数

       我们可以很简单的推导出基本情况,如果没有房间,小偷就得被饿死,如果只有一家,小偷无可奈何,只能被迫的去偷这家,如果有两家,小偷肯定回去偷金额比较多的那家

     dp[0]=nums[0];dp[1]=Math.max(nums[0],nums[1]);

解题的入参判断肯定少不了,这种入参判断能为你解决不少的麻烦

       if(n==0){return 0;}if(n==1){return nums[0];}

那么我们的代码 就已经写完了

public int rob(int[] nums) {int n=nums.length;if(n==0){return 0;}if(n==1){return nums[0];}int [] dp=new int[n];dp[0]=nums[0];dp[1]=Math.max(nums[0],nums[1]);for(int i=2;i<n;i++){dp[i]=Math.max(dp[i-1],nums[i]+dp[i-2]);}return dp[n-1];}

       打家劫舍II的基本过程和I差不多,就是从一个直线型房屋排列转换为环形房屋排列,这种就应该考虑是n-1房子和0房子偷不偷的问题,其实可以分为两个数组,分别计算可以偷取的最大金额,最后取最大值就ok了,我们下面讲打家窃舍III

       我不得不说,这小偷的数据结构学的其实蛮好的,什么样的房屋排列都能让他想到数据结构这块,利用算法的知识进行解决,不当码农可惜了

 来让我们言归正传

 对于我们的选择是每个节点是否偷取决定着我们最后的结果

 如果偷的话,情况又是如何?不偷的时候情况又是怎样的?

 

       看到这幅图大家会想到什么?树的层序遍历,但是树的层序遍历在这里可是不适用的,因为这道题中的有些情况是通过不了,所以我们换种思维想一想,这种题是不是可以用递归的方式解决

 假设我们的当前节点是root,递归函数是rob

偷:当前的节点的金额数+rob(节点左树的子左树)+rob(节点左树的右树)+rob(节点右树的左树)+rob(节点右树的右树)

不偷:rob(节点的左树)+rob(节点的右树)

 int rob=root.val+(root.left==null?0:rob(root.left.left)+rob(root.left.right))+(root.right==null?0:rob(root.right.right)+rob(root.right.left));int rob_not=rob(root.left)+rob(root.right);

 这种递归大概率会超时,所以我们加一个记忆化数组,不用再进行重复计算(进行剪枝)

  Map<TreeNode,Integer> map=new HashMap<>();if(map.containsKey(root)){return map.get(root);}

       该题的大致流程就已经讲完了,希望大家可以看的开心,不懂的可以在评论区问我,我看到的话会给大家一一解答

   Map<TreeNode,Integer> map=new HashMap<>();public int rob(TreeNode root) {if(root==null){return 0;}if(map.containsKey(root)){return map.get(root);}int rob=root.val+(root.left==null?0:rob(root.left.left)+rob(root.left.right))+(root.right==null?0:rob(root.right.right)+rob(root.right.left));int rob_not=rob(root.left)+rob(root.right);int max=Math.max(rob,rob_not);map.put(root,max);return max;}

http://www.lryc.cn/news/109724.html

相关文章:

  • 【Deepsort】C++版本Deepsort编译(依赖opencv,eigen3)
  • Synchronized锁升级过程
  • 汽车电子功能安全
  • ARM进阶:内存屏障(DMB/DSB/ISB)的20个使用例子详解
  • Cpp学习——模板
  • HTTP 协议 版本详解
  • PHP语言基础知识(超详细)
  • Flex弹性盒子的项目属性
  • 广州银行信用卡中心:强化数字引擎安全,实现业务稳步增长
  • 【Rust日报】2023-08-03 - Polars 获约 400 万美元种子轮融资
  • 装修小程序,开启装修公司智能化服务的新时代
  • 使用PHP和Redis实现简单秒杀功能
  • C#开发FFMPEG例子(API方式) FFmpeg拉取udp组播流并播放
  • Android性能优化—图片优化
  • 如何搭建自动化测试框架?资深测试整理的PO模式,一套打通自动化...
  • 软件外包开发的GO语言特点
  • 【深度学习Week4】MobileNet_ShuffleNet
  • 649. Dota2 参议院
  • 无人机管控平台,推动电力巡检管理水平提升
  • 阿里云平台WoSignSSL证书应用案例
  • 服务器时钟同步
  • AMEYA360:瑞萨电子MCU和MPU产品线将支持Microsoft Visual Studio Code
  • JSP--Java的服务器页面
  • 07 Ubuntu中使用poetry工具管理python环境——巨详细!!!
  • 射影平面 与 射影变换
  • (202307)wonderful-sql:决胜秋招(task6)
  • Scratch 教程:如何实现文本分割
  • 安全基础 --- 编码(02)+ form表单实现交互
  • 华为OD机考真题--五子棋--带答案
  • 把网站改为HTTPS访问方法