Leetcoder Day42| 动态规划part09 打家劫舍问题

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 。

提示:

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

本题的出发点是确定当前状态是否偷,而如果当前偷了,前一个和后一个就不能偷,所以也是和前面的状态有依赖关系,因此还是动态规划问题:

  1. 确定dp数组以及下标的含义:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]
  2. 确定递推公式:如果偷第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个房,所以dp[i]=max(dp[i-1], dp[i-2]+nums[i])
  3. 初始化:因为需要用到i-1和i-2所以需要知道dp[0]和dp[1],dp[0]表示偷下标为0的屋子最多可以偷的金额,就是nums[0],dp[1]就是nums[0]和nums[1]的最大值
  4. 遍历顺序:从前向后,因为dp[i]需要根据i-1和i-2的状态推出来
class Solution {public int rob(int[] nums) {int[] dp =new int[nums.length];dp[0]=nums[0];if(nums.length==1) return nums[0];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];}
}

213. 打家劫舍 II

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

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

示例 1:

  • 输入:nums = [2,3,2]

  • 输出:3

  • 解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。

提示:

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

本题和打家劫舍1的区别就在于房子是连着的,所以下标含义和递推逻辑不变,需要重新考虑初始化。这里多了一个需要判断的条件就是:i是否为最后一个房子,如果是,则需要考虑第一个房子偷不偷的问题,如果第一个房子没有被选,则i 就只跟i-1是否被选有关系。所以可以分两种情况分别计算,最后判断哪个值大,就返回哪个值。所以这里初始化两次,一次是第一间房一定不被抢,一个是第一间房一定被抢。

class Solution {public int rob(int[] nums) {int n = nums.length;if (n == 0) return 0;if (n == 1) return nums[0];if (n == 2) return Math.max(nums[0], nums[1]);int[] dp = new int[n];dp[0] = nums[0];dp[1] = Math.max(nums[0], nums[1]);for (int i = 2; i < n - 1; i++) {dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);}int resultWithFirst =dp[n-2]; //选择第一间,则最后一个房子就不会被选,那么dp[n-1]=dp[n-2]dp[0] = 0; // 重新初始化dp[0],第一间房子不被抢dp[1] = nums[1]; // 重新初始化dp[1]for (int i = 2; i < n; i++) {// 第一间房子不被抢的情况下,最后一间可以被抢dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);}int resultWithoutFirst = dp[n - 1]; return Math.max(resultWithoutFirst, resultWithFirst);}
}

337.打家劫舍 III

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。

本题思维和之前的打家劫舍是一样的,只不过数据形式换成了树,需要对树进行遍历,不能同时抢的条件变成抢了父亲节点就不能抢其对应的孩子节点,抢了孩子节点就不能抢对应的父亲节点。动态规划其实就是使用状态转移容器来记录状态的变化,这里可以使用一个长度为2的数组,记录当前节点偷与不偷所得到的的最大金钱。

对于遍历树,就又需要用到递归,下面对应递归三部曲:

  1. 确定递归函数的参数和返回值:要计算一个节点偷与不偷所得到的金钱,所以返回值就是一个长度为2的数组,对于动态规划就是返回一个dp数组,标为0记录不偷该节点所得到的的最大金钱,下标为1记录偷该节点所得到的的最大金钱。
  2. 确定终止条件:在遍历的过程中,如果遇到空节点的话,很明显,无论偷还是不偷都是0,所以就返回0,这也相当于dp数组的初始化
  3. 确定遍历顺序:需要进行后续遍历,因为需要通过递归函数的返回值做下一步计算,遍历顺序为左右根
  4. 确定单层递归的逻辑:如果偷当前节点,就不考虑左右孩子,也就是val1=cur.root+left[0],如果不偷当前节点,判断val2 = max(left[0], left[1]) + max(right[0], right[1]);

所以本题的含义val[0]代表不偷,val[1]代表偷,最后判断val[0]和val[1]谁大

class Solution {public int[] traversal(TreeNode root){int[] val=new int[2];if(root==null) return val;int[] left= traversal(root.left);int[] right=traversal(root.right);//不偷val[0]=Math.max(left[0],left[1])+Math.max(right[0],right[1]);//偷val[1]=root.val+left[0]+right[0];return val;}public int rob(TreeNode root) {int[] val=traversal(root);return Math.max(val[0], val[1]);}
}

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

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

相关文章

从新手到大师:顶级PPT学习网站推荐,让你的幻灯片脱颖而出!

介绍&#xff1a;PowerPoint&#xff0c;简称PPT&#xff0c;是微软公司开发的一款演示程序&#xff0c;也是Microsoft Office套件的重要组成部分之一。 PPT允许用户通过幻灯片的形式创建和展示信息&#xff0c;这些幻灯片可以包含文本、图形、图表、视频、音频等多种元素。用户…

Linux-网络-011

1网络协议模型 1.1【OSI】协议模型 1.1.1应用层 实际发送的数据应用层:HTTP 超文本传输协议HTTPS FTP 文件传输协议TFTP 简单文本传输协议SMTP 邮件传输协议MQTT TELNET ..1.1.2表示层 发送的数据是否加密1.1.3会话层 是否建立会话连接1.1.4传输层 数据…

解决 Chrome 无法代理外网,但Safari等其他软件可以

文章目录 1. 问题2. 解决方法 1. 问题 开启代理之后&#xff0c;Chrome 浏览器仍然无法访问外网。但是用 Mac 的 Safari 浏览器或者其他的软件已经可以访问外网。 2. 解决方法 发现 Chrome 浏览器的某些拓展程序会影响代理&#xff0c;可以关闭 Chrome 的拓展程序试试&#…

二维码门楼牌管理系统应用场景:数据管理的智慧新选择

文章目录 前言一、数据管理部门的智慧工具二、助力决策制定与优质服务提供三、二维码门楼牌管理系统的优势四、展望未来 前言 随着科技的飞速发展&#xff0c;二维码门楼牌管理系统正逐渐成为城市管理的智慧新选择。该系统不仅提升了数据管理效率&#xff0c;还为政府和企业提…

软件系统开发安全指南-word

应用系统设计安全主要涵盖以下几点&#xff1a; 1、应用系统架构安全设计 2、应用系统软件功能安全设计 3、应用系统存储安全设计 4、应用系统通讯安全设计 5、应用系统数据库安全设计 应用系统测试安全包含&#xff1a; 1、测试前置要求 2、测试方法及测试内容 3、测试环境及人…

idea Gradle 控制台中文乱码

如下图所示&#xff0c;idea 中的 Gradle 控制台中文乱码&#xff1a; 解决方法&#xff0c;如下图所示&#xff1a; 注意&#xff1a;如果你的 idea 使用 crack 等方式破解了&#xff0c;那么你可能需要在文件 crack-2023\jetbra\vmoptions\idea.vmoptions 中进行配置&#xf…

Linux 开发工具 yum、git、gdb

目录 一、yum 1、软件包 2、rzsz 3、注意事项 4、查看软件包 5、安装软件 6、卸载软件 二、git操作 1、克隆三板斧 2、第一次使用会出现以下情况&#xff1a; 未配置用户名和邮箱&#xff1a; push后弹出提示 三、gdb使用 1、背景 2、使用方法 例一&#xff1a…

谷歌seo外链怎么发?

谷歌SEO外链建设&#xff0c;说白了&#xff0c;就是让别的网站放一条或几条链接指向你的网站&#xff0c;这事听着简单&#xff0c;但你凭什么在别人的地盘放自己网站的链接&#xff0c;就算真的能放自己网站的链接&#xff0c;你又是否能保证你发的内容跟自己网站相关&#x…

OpenStack之Nova

一 、Nova 使用OpenStack Compute来托管和管理云计算系统。 OpenStack Compute是基础架构即服务 &#xff08;IaaS&#xff09;系统的主要部分。 主要模块在Python中实现&#xff1a; 1因为认证&#xff0c;与OpenStack 身份认证keystone 交互。 2因为磁盘和服务器镜像&#xf…

你不知道的Postman的Mock接口测试,看这一篇就够了

前言 创建Mock服务 你可以从Postman已有的测试集(Collection)中创建Mock Server或者直接创建Mock Server&#xff08;我们这里选择从已有的测试集中创建Mock Server&#xff09; Mock server详细配置页面&#xff0c;在此页面中我们可以设置&#xff1a; Name the mock serv…

Pytorch从零开始实战20

Pytorch从零开始实战——指定生成手势图像 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——指定生成手势图像环境准备模型选择模型训练可视化分析生成指定图像总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c…

使用Python及Pandas库高效处理大规模CSV数据集:实战解析与代码案例

引言 在数据科学与大数据领域&#xff0c;Python凭借其丰富的数据处理库如Pandas而广受青睐。Pandas库尤其擅长处理表格型数据&#xff0c;如CSV文件&#xff0c;它可以高效地执行读取、清洗、操作和分析大量数据的任务。本文将带领读者深入探讨如何利用Python和Pandas库处理大…