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

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

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

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

相关文章

中国青年网投稿三下乡社会实践稿件方法

文稿要求 实践纪实类文稿 &#xff08;1&#xff09;标题&#xff1a;10-30个汉字为宜&#xff0c;要用一句话标题&#xff0c;清楚叙述开展社会实践的学校、内容等基本信息。 &#xff08;2&#xff09;正文&#xff1a;表述要流畅&#xff0c;不可写宣传稿&#xff0c;要注…

文件中找TOPK问题

一.TOP—K问题简介&#xff1a; TOP-K 问题&#xff1a;即求数据结合中前 K 个最大的元素或者最小的元素&#xff0c;一般情况下数据量都比较大 。 比如&#xff1a;专业前 10 名、世界 500 强、富豪榜、游戏中前 100 的活跃玩家等。 对于 Top-K 问题&#xff0c;能想到的最简…

c# - 运算符 << 不能应用于 long 和 long 类型的操作数

Compiler Error CS0019 c# - 运算符 << 不能应用于 long 和 long 类型的操作数 处理方法 特此记录 anlog 2024年5月30日

个人笔记-随意记录

常见问题&#xff1f; 1.linux重启服务 端口被占用如何解决&#xff1f; 查看某个端口被占用的进程 netstat -tulnp | grep :23454 强制杀死进程 kill -9 1776 重启服务即可

无人机、机器人10公里WiFi远距离图传模块,实时高清视频传输,飞睿CV5200模组方案,支持mesh自组网模块

在快速发展的物联网时代&#xff0c;远距离无线通信技术已成为连接各种智能设备的关键。无人机、安防监控、机器人等领域对数据传输的距离和速度要求越来越高。 公里级远距离WiFi模组方案可以通过多种技术和策略的结合来实现无人机和机器人之间的高效通信传输。 飞睿智能CV52…

Java排序算法汇总篇,八种排序算法

排序算法汇总: Java排序算法(一)&#xff1a;冒泡排序 Java排序算法(二)&#xff1a;选择排序 Java排序算法(三)&#xff1a;插入排序 Java排序算法(四)&#xff1a;快速排序 Java排序算法(五)&#xff1a;归并排序 Java排序算法(六)&#xff1a;希尔排序 Java排序算法(…

PPT 隐藏开启对象图层

目录预览 一、问题描述二、解决方案三、参考链接 一、问题描述 制作PPT的时候&#xff0c;有时候需要在一张PPT放置多个依次出现的内容&#xff0c;然后设置对应的动画&#xff0c;要是需要对某个内容进行修改的话&#xff0c;就会很不方便&#xff0c;这个时候就需要使用&…

代码随想录第24天|回溯part4 寻找切割点

93.复原ip地址 寻找切割点&#xff0c;但是需要注意的是&#xff0c;切割点&#xff08;即.号&#xff09;只有三个 将需要拼凑的值先放进一个数组里&#xff0c;等满足条件后再将其拼成字符串 class Solution { public:vector<string> res;vector<int> path;int …

opencv-python(五)

opencv的颜色通道中顺序是B&#xff0c;G&#xff0c;R。 图像属性 import cv2img cv2.imread(jk.jpg) print(fshape{img.shape}) print(fsize{img.size}) print(fdtype{img.dtype}) shape&#xff1a;图像像素的行&#xff0c;列&#xff0c;通道 size&#xff1a;行数 X …

用贪心算法计算十进制数转二进制数(整数部分)

十进制整数转二进制数用什么方法&#xff1f;网上一搜&#xff0c;大部分答案都是用短除法&#xff0c;也就是除2反向取余法。这种方法是最基本最常用的&#xff0c;但是计算步骤多&#xff0c;还容易出错&#xff0c;那么还有没有其他更好的方法吗&#xff1f; 一、短除反向取…

WMS仓储管理系统高效驱动制造企业物料管理

在现代制造业的快速发展中&#xff0c;仓储管理作为供应链的核心环节&#xff0c;其效率直接影响到企业的生产力和市场竞争力。随着科技的进步&#xff0c;实施WMS仓储管理系统逐渐成为推动仓储管理向智能化转型的关键力量。本文将深入探讨WMS仓储管理系统如何以创新的方式驱动…

软件系统测试的定义和测试内容介绍

一、什么是软件系统测试? 软件系统测试是指对软件系统的功能、性能、可靠性、稳定性等方面进行全面检查和验证的过程。其目的是发现潜在的问题、缺陷和风险&#xff0c;并确保软件系统的质量和稳定性。 软件系统测试可以分为多个阶段&#xff0c;包括单元测试、集成测试、系…

OBS插件--Spout输入与输出

Spout是什么&#xff1f; Spout是用于Microsoft Windows的视频帧共享系统,它允许应用程序以类似于Mac上的Syphon的方式共享OpenGL纹理。 其主要目的是允许应用程序实时共享帧&#xff0c;而无需显著的性能开销。这一功能在多个领域有着广泛的应用&#xff0c;尤其是在实时视频…

【python】成功解决“TypeError: not enough arguments for format string”错误的全面指南

成功解决“TypeError: not enough arguments for format string”错误的全面指南 一、引言 在Python编程中&#xff0c;TypeError: not enough arguments for format string错误是一个常见的字符串格式化问题。这个错误通常发生在使用str.format()方法时&#xff0c;提供的参数…

【DMG80480T070_05WTR】文本显示、数据变量显示、基本图形显示、实时曲线功能及串口下载流程(串口屏)

这篇文章写给自己看的&#xff0c;要不然明天就忘完了。 首先新建一个工程&#xff0c;名称路径自拟。 导入一张图片&#xff0c;名字从00开始&#xff0c;图片放到本工程的DWIN_SET下面就行&#xff0c;后面如果没有特殊说明&#xff0c;生成的配置或者放入的图片全都放在该文…

三种常见的报表模板,省时又方便

前言 在业务应用和数据分析中&#xff0c;报表是一种常见的数据展示形式&#xff0c;可以帮助用户更直观地理解和解读数据。然而&#xff0c;每次创建和设计一款报表都需要花费大量的时间和精力。为了提高报表设计的效率&#xff0c;本文小编以葡萄城公司的嵌入式BI工具——Wy…

什么样的人适合成为产品经理

产品经理就好比是大楼的设计师&#xff0c;如果没有好的设计理念&#xff0c;好的洞察力&#xff0c;很难设计出让住户心满意足的房子。产品经理也是如此。 01要有创新思维和敏锐商业洞察力 做了很长时间的产品经理了&#xff0c;发现大部分产品经理基本上都是墨守成规&#…

AI写代码:我用kimi生成了一个设备节点监控网站,完美实现功能

更多精彩内容在公众号。 这一次继续用kimi来完成一个网站的初步搭建。这次是用来搭建一个节点监控网站。需求是通过输入节点Ip地址&#xff0c;用户名&#xff0c;密码得到远端节点的IP&#xff0c;CPU信息&#xff0c;内存信息&#xff0c;硬盘信息&#xff0c;网络收发包信息…

【Node】node的Events模块(事件模块)的介绍和使用

文章目录 简言EventsPassing arguments and this to listeners 向监听器传递参数Asynchronous vs. synchronous 异步和同步Handling events only once 只一次处理事件Error events 错误事件Capture rejections of promises 捕捉拒绝承诺的情况Class: EventEmitter 事件类Event:…

神经网络是什么?有什么作用?

人工智能是当前的热门科技领域&#xff0c;在自动驾驶、金融服务、智能家居、零售和电商、工业制造、医疗领域、教育领域、交通领域、娱乐领域、能源管理、农业、航空航天等很多领域都有越来越多的应用。 发展人工智能&#xff0c;离不开算力&#xff08;芯片&#xff09;、算…