动态规划——打家劫舍问题

198. 打家劫舍

问题描述

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

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

示例 1:

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

示例 2:

输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12 。

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 400

解题思路与代码实现

dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]

决定dp[i]的因素就是第i房间偷还是不偷。

如果偷第i房间,那么dp[i] = dp[i - 2] + nums[i] ,即:第i-1房一定是不考虑的,找出 下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为dp[i-2] 加上第i房间偷到的钱。

如果不偷第i房间,那么dp[i] = dp[i - 1],即考 虑i-1房,(注意这里是考虑,并不是一定要偷i-1房

class Solution {
    public int rob(int[] nums) {
        if (nums.length == 1) {
            return nums[0];
        }
        int n = nums.length;
        int[] dp = new int[101]; // dp[i]:打劫下标i的房屋所能得到的最大金额
        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];
    }
}

踩坑点

213. 打家劫舍 II

问题描述

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

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

示例 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

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 1000

解题思路与代码实现

数组首尾成环,我们可以用之前的方法分别计算[0,n-2]和[1,n-1]区间的最大金额,在进行比较去最大值。

class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0)
            return 0;
        int len = nums.length;
        if (len == 1)
            return nums[0];
        return Math.max(robAction(nums, 0, len - 2), robAction(nums, 1, len - 1));
    }

    int robAction(int[] nums, int start, int end) {
        if (start == end)
            return nums[start];
        int[] dp = new int[nums.length]; // 定义dp数组
        dp[start] = nums[start];
        dp[start + 1] = Math.max(nums[start], nums[start + 1]);
        for (int i = start + 2; i <= end; i++) {
            // 递推方程
            dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
        }
        return dp[end];
    }
}

踩坑点

如何解决首尾成环的情况

337. 打家劫舍 III

问题描述

  • 小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root

    除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。

    给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额

    示例 1:
    在这里插入图片描述

    输入: root = [3,2,3,null,3,null,1]
    输出: 7 
    解释: 小偷一晚能够盗取的最高金额 3 + 3 + 1 = 7
    

    示例 2:

在这里插入图片描述

输入: root = [3,4,5,1,3,null,1]
输出: 9
解释: 小偷一晚能够盗取的最高金额 4 + 5 = 9

提示:

  • 树的节点数在 [1, 104] 范围内
  • 0 <= Node.val <= 104

解题思路与代码实现

本题关键是要讨论当前节点抢还是不抢:

如果抢了当前节点,两个孩子就不能继续抢;

如果没抢当前节点,就可以考虑抢左右孩子;

具体是否要抢当前节点,取决于两种方案哪个能抢到的金额更高

class Solution {
    public int rob(TreeNode root) {
        int[] res = robAction(root);
        return Math.max(res[0], res[1]);
    }

    // 返回长度为2的数组,下标0为偷root节点的价值,下标为不偷root节点的价值
    private int[] robAction(TreeNode root) {
        if (root == null) {
            return new int[] { 0, 0 };
        }
        int[] left = robAction(root.left);
        int[] right = robAction(root.right);
        // 偷父节点代表的房屋
        int val1 = root.val + left[1] + right[1];
        // 不偷父节点,偷左右孩子节点
        int val2 = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        return new int[] { val1, val2 };
    }
}

也可以采用记忆化递归求解

class Solution {
    // 记忆化递归
    private HashMap<TreeNode,Integer> map = new HashMap<>();
    public int rob(TreeNode root) {
        return robAction(root);
    }
    // 采用后续遍历+记忆化递归
    private int robAction(TreeNode root){
        if(root == null){
            return 0;
        }
        if(map.containsKey(root)) return map.get(root);
        // 偷父节点代表的房屋
        int val1 = root.val;
        if(root.left != null) { // 偷左孩子的孩子节点
            val1 += robAction(root.left.left) + robAction(root.left.right);
        }
        if(root.right!=null){   // 偷右孩子的孩子节点
            val1 += robAction(root.right.left) + robAction(root.right.right);
        }
        // 不偷父节点,偷左右孩子节点
        int val2 = robAction(root.left) + robAction(root.right);
        int val = Math.max(val1,val2);
        map.put(root,val);  // map记录,避免重复计算
        return val;
    }
}

踩坑点

在树的背景下计算,递推方程的变化

参考链接:
代码随想录-打家劫舍
代码随想录-打家劫舍II
代码随想录-打家劫舍III

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MathorCup挑战赛获奖名单公示,第九届研讨会及颁奖典礼即将举行

近日&#xff0c;备受瞩目的2024年第十四届MathorCup高校数学建模挑战赛圆满落幕&#xff0c;竞赛组委会于近日公示了获奖名单初稿。本届竞赛自2024年4月12日至16日举行&#xff0c;吸引了来自全国740所高校的9119支队伍踊跃参与&#xff0c;其中包括本科生、研究生、专科生及教…

Java流程控制习题--打印三角形及debug运用

1.打印三角形 使用for循环的嵌套进行运算&#xff0c;思考代码实现的思维方式 2.debug可显示代码每一步的运行步骤&#xff0c;使我们更好的了解代码的运行&#xff0c; debug使用方法&#xff1a;在代码的左侧排序处单机&#xff0c;在点击右上角的蜘蛛图标即可

springboot+elementui健康饮食系统

此系统是springboot健康饮食管理平台 得简化版&#xff0c;适合期末大作业 系统包括 管理员端和用户端 1.用户端注册即可登录到用户端&#xff0c;用户端包括首页轮播图&#xff0c;以及个人中心&#xff0c;个人信息修改&#xff0c;头像修改&#xff0c;后台根据用户信息&am…

liunx配置网络的命令

liunx配置网络的命令 文章目录 liunx配置网络的命令ifconfig命令查看路由表信息netstat命令ss命令lsof命令ping 命令nslookup命令 ifconfig命令 ifconfig:显示正在工作的网卡&#xff0c;启动的设备 ifconfig -a 展示所有设备 ens33: flags4163<UP,BROADCAST,RUNNING,MUL…

Flutter开发效率提升1000%,Flutter Quick教程之定义Api(四)

现在我们来讲讲&#xff0c;如何建立Api 响应数据的变量。 这个变量&#xff0c;本质上就是对根据json数据生成model的引用。 这个name就是引用名。 这个path&#xff0c;就是引用的Model Data里面的具体字段&#xff0c;在实际操作过程中&#xff0c;校验是由右边的json数据…

Pikachu靶场下载、配置

目录 下载 配置 新版小蓝皮 搭建网站 搭建数据库 初始化靶场 旧版小绿皮 配置数据库 配置网站 下载 GitHub下载地址&#xff1a; 百度网盘&#xff1a;https://pan.baidu.com/s/1j2WpdLvwAbmpAH76d_yitw?pwdwf8j 提取码&#xff1a;wf8j 迅雷链接&#xff1a;http…

LLC开关电源开发:第三节,LLC电路原理图及开环仿真

LLC开关电源开发&#xff1a;第三节&#xff0c;LLC电路原理图 第三节&#xff0c;LLC电路原理图文章目录 一、开发板指标二、原理图简介1.LLC主功率电路2.输入滤波电路3.烧录口及复位电路4.DSP供电电路5.输出采样电路6.DSP外围电路7.指示灯电路8.调压滑动变阻器电路9.隔离驱动…

性能测试学习-基本使用-元件组件介绍(二)

jmeter优点是&#xff1a;开源免费&#xff0c;小巧&#xff0c;丰富的学习资料和扩展组件 缺点是&#xff1a;1.不支持IP欺骗&#xff0c;分析和报表能力相对于LR欠缺精确度&#xff08;以分钟为单位&#xff09; 工具用户量分析报表IP欺骗费用体积扩展性Loadrunner多(万)精…

Android百度人脸识别3.0配置

JDK 必须是16的版本 如果报错的错误是"opens java.io" org.gradle.jvmargs -Xmx2048M -Dkotlin.daemon.jvm.options\"-Xmx2048M" --add-exportsjava.base/sun.nio.chALL-UNNAMED --add-opensjava.base/java.langALL-UNNAMED --add-opensjava.base/java.…

Android 绑定服务的5个问题。

1.android studio 目录结构改变了。为什么会报R 资源文件找不到。 在写项目的时候经常需要改到。 gradle文件里的域名名字要改变下。 2.Caused by: android.app.BackgroundServiceStartNotAllowedException: Not allowed to start service Intent { cmpcom.zjtzsw.sbkDevice/…

Chisel入门——在windows下vscode搭建|部署Scala2.13.3开发环境|用Chisel点亮FPGA小灯等实验

文章目录 前言Chisel介绍 一、vscode搭建scala开发环境1.1 安装Scala官方插件1.2 创建hello_world.scala文件1.3 确认java的版本(博主使用的是1.8)1.4 下载Scala Windows版本的二进制文件1.5 配置环境变量1.6 交互模式测试一下1.7 vscode运行scala 二、windows安装sbt2.1 下载s…

JMeter Plugins Manager---插件安装

参考文章&#xff1a;https://blog.51cto.com/u_14126/6291032 需求&#xff1a; 安装【jpgc - Standard Set】插件 常用插件&#xff1a; 点击下载–报错如下&#xff1a; Failed to apply changes:Cannotapplychanges:Haveno write accessforJMeterdirectories,notpossib…

【机器学习数据挖掘】基于ARIMA 自回归积分滑动平均模型的销售价格库存分析报告 附完整python代码

资源地址&#xff1a;Python数据分析大作业 4000字 图文分析文档 销售分析 完整python代码 ​ 完整代码分析 同时销售量后1000的sku品类占比中&#xff08;不畅销产品&#xff09;如上&#xff0c;精品类产品占比第一&#xff0c;达到66.7%&#xff0c;其次是香化类产品&#…

Transformers实战03-PEFT库使用LORA方法微调。

文章目录 简介PEFTLORA方法Vision Transformer (ViT) lora方法实战模型选择google/vit-base-patch16-224-in21kgoogle/vit-base-patch16-224 数据集模型PEFT configuration and model训练预测 简介 PEFT PEFT&#xff08;Parameter-Efficient Fine-Tuning&#xff09;是一个用…

开窗函数!

开窗函数&#xff08;Window Function&#xff09;是SQL中的一种高级功能&#xff0c;允许你在一组相关行&#xff08;一个“窗口”&#xff09;上执行聚合操作&#xff0c;而不像传统聚合函数&#xff08;如SUM(), AVG(), COUNT()&#xff09;那样将所有匹配行合并成单个汇总行…

这就是英伟达 CEO 黄仁勋所说的人工智能“下一波浪潮”|TodayAI

在台湾一年一度的科技展 COMPUTEX 开幕前的周日&#xff0c;英伟达&#xff08;Nvidia&#xff09;首席执行官黄仁勋&#xff08;Jensen Huang&#xff09;表示&#xff0c;机器人和“理解物理定律的 AI”将成为下一波技术浪潮。他指出&#xff0c;英伟达目前正在推动生成式人工…

[Redis]Zset类型

Zset有序集合相对于字符串、列表、哈希、集合来说会有一些陌生。 它保留了集合不能有重复成员的特点&#xff0c;但与集合不同的是&#xff0c;有序集合中的每个元素都有一个唯一的浮点类型的分数&#xff08;score&#xff09;与之关联&#xff0c;着使得有序集合中的元素是可…

c语言:自定义类型(枚举、联合体)

前言&#xff1a; c语言中中自定义类型不仅有结构体&#xff0c;还有枚举、联合体等类型&#xff0c;上一期我们详细讲解了结构体的初始化&#xff0c;使用&#xff0c;传参和内存对齐等知识&#xff0c;这一期我们来介绍c语言中的其他自定义类型枚举和联合体的知识。 1.位段 …

jupyter notebook anaconda环境下查看|加载|更换内核

文章目录 1 问题复现2 查看内核位置3 调整python解释器位置 1 问题复现 在conda虚拟环境中使用pip安装相应package&#xff0c; 但是在jupyter notebook中加载该package时报错 [ERROR]ModuleNotFoundError: No module named shap 此时&#xff0c;除去包安装出现问题以外&am…

ARM学习(28)NXP 双coreMCU IMX1160学习

笔者最近接触到一块IMXRT1160的双core板子&#xff0c;特依次来记录学习一下 1、IMXRT1160 板子介绍 介绍一下NXP的Demo板子&#xff0c;是一个双core的板子&#xff0c;Cortex-M7和Cortex-M4&#xff0c;总计1MB的RAM空间&#xff0c;256KB的ROM空间&#xff0c;提供了丰富的…