【每日力扣】198.打家劫舍与213.打家劫舍II与337.打家劫舍 III

news2024/10/5 17:25:18

在这里插入图片描述

🔥 个人主页: 黑洞晓威
😀你不必等到非常厉害,才敢开始,你需要开始,才会变的非常厉害

198.打家劫舍

力扣题目链接(opens new window)

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

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

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

这道题目可以使用动态规划(Dynamic Programming, DP)的策略来解决。动态规划是一种用来解决需要考虑多个子问题的优化问题的方法,在此问题中,我们需要决定在每一步中是偷窃当前的房屋还是跳过,以便总金额最大化,同时不触发警报。

解题思路

  1. **状态定义:**设dp[i]表示到第i个房屋时能偷窃到的最大金额,i从0开始。
  2. **状态转移:**对于每个房屋i,小偷有两个选择:偷或不偷。
    • 如果小偷选择偷当前房屋i,那么他不能偷窃前一个房屋i-1,所以dp[i] = nums[i] + dp[i-2]
    • 如果小偷选择不偷当前房屋i,那么dp[i] = dp[i-1],因为他可以保持到i-1为止的最大金额。
    • 综上所述,我们可以得到状态转移方程:dp[i] = max(dp[i-1], nums[i] + dp[i-2])
  3. 初始条件:
    • 当只有一个房屋时,偷这个房屋将获得最大收益,即dp[0] = nums[0]
    • 当有两个房屋时,选择金额较大的那个房屋,所以dp[1] = max(nums[0], nums[1])
  4. **返回值:**最终,dp[n-1]将表示偷窃前n个房屋可以获得的最大金额,其中n是输入数组nums的长度。

代码实现

public class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        if (nums.length == 1) return nums[0];
        int n = nums.length;
        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];
    }
}

213.打家劫舍II

力扣题目链接(opens new window)

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

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

示例 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 = [0]
  • 输出:0

解题思路

针对这个问题,我们可以采取的策略是根据打家劫舍I的解题思路,由于房屋是形成一个环的,所以有一个新的限制条件:不能同时偷第一个房屋和最后一个房屋。这意味着我们有两种情况需要考虑并取其中的最大值:

  • 偷第一间到倒数第二间房屋。
  • 偷第二间到最后一间房屋。

我们可以重用打家劫舍I的解决方案,将这两种情况都求一遍最大值,然后取两者中的较大值即可。具体实现时,我们可以定义一个辅助函数,用于计算在指定起始和结束位置的条件下能够偷窃到的最高金额。

代码实现

public class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int n = nums.length;
        // 当房屋数量小于三时的特殊处理
        if (n == 1) return nums[0];
        if (n == 2) return Math.max(nums[0], nums[1]);
        // 分两种情况,不偷第一间或不偷最后一间
        return Math.max(robRange(nums, 0, n - 2), robRange(nums, 1, n - 1));
    }

    // 辅助函数,实现打家劫舍I的逻辑,但是在指定的起始和结束位置
    private int robRange(int[] nums, int start, int end) {
        if (start == end) {
            return nums[start];
        }
        int[] dp = new int[nums.length];
        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], nums[i] + dp[i - 2]);
        }
        return dp[end];
    }
}

337.打家劫舍 III

力扣题目链接(opens new window)

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

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

image-20240405110112427 image-20240405110128212

解题思路

该问题可以通过树形动态规划(也称为后序遍历深度优先搜索)来解决。对于树中的任何一个节点,小偷有两个选择:偷或不偷。

  • 如果偷当前节点,那么就不能偷其子节点;
  • 如果不偷当前节点,那么可以选择偷取其子节点。

因此,对于每个节点,我们需要返回两个信息:偷该节点时的最大金额与不偷该节点时的最大金额。

  1. 对于树的每一个节点,返回一个大小为2的数组,其中arr[0]存放不偷该节点时的最大金额,arr[1]存放偷该节点时的最大金额。
  2. 不偷当前节点时的最大金额等于左子节点偷或不偷的最大值加上右子节点偷或不偷的最大值。
  3. 偷当前节点时的最大金额等于当前节点的金额加上左子节点不偷时的金额加右子节点不偷时的金额。
  4. 使用后序遍历的方式遍历整棵树,依次求出每个节点偷与不偷时的最大金额。
  5. 根节点的最大金额即为答案。

代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int rob(TreeNode root) {
        int[] result = robSub(root);
        return Math.max(result[0], result[1]);
    }

    private int[] robSub(TreeNode node) {
        if (node == null) {
            return new int[2];
        }
        int[] left = robSub(node.left);
        int[] right = robSub(node.right);

        // res[0]代表不偷该节点时的最大金额,res[1]代表偷该节点时的最大金额
        int[] res = new int[2];
        res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        res[1] = node.val + left[0] + right[0];

        return res;
    }
}

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

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

相关文章

谷歌AI搜索革新:探索高级搜索服务背后的未来趋势

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Redis -- 缓存穿透问题解决思路

缓存穿透 &#xff1a;缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;这些请求都会打到数据库。 常见的解决方案有两种&#xff1a; 缓存空对象 优点&#xff1a;实现简单&#xff0c;维护方便 缺点&#xff1a; 额外…

STM32之HAL开发——不同系列SPI功能对比(附STM32Cube配置)

不同系列STM32——SPI框图 F1系列框图 F4系列框图 TI模式时序图特性 F7系列框图 H7系列框图 注意&#xff1a;F7系列以及H7系列支持Quad-SPI模式&#xff0c;可以连接单&#xff0c;双或者四条数据线的Flash存储介质。 SPI——Cube配置流程 RCC时钟源配置 SYS系统调试模式配…

【SCI绘图】【箱型图系列1 python】多类对比及各类下属子类对比

SCI&#xff0c;CCF&#xff0c;EI及核心期刊绘图宝典&#xff0c;爆款持续更新&#xff0c;助力科研&#xff01; 本期分享&#xff1a; 【SCI绘图】【箱型图系列1】多类对比各类下属子类对比 文末附带完整代码&#xff1a; 1.环境准备 python 3 from matplotlib import p…

Go语言hash/fnv应用实战:技巧、示例与最佳实践

Go语言hash/fnv应用实战&#xff1a;技巧、示例与最佳实践 引言hash/fnv概览使用hash/fnv的初步步骤导入hash/fnv库创建哈希器实例 hash/fnv在实际开发中的应用生成唯一标识符数据分片与负载均衡快速查找 高级技巧和最佳实践避免哈希碰撞动态调整哈希表大小利用sync.Pool优化哈…

【蓝桥杯】GCD与LCM

一.概述 最大公约数&#xff08;GCD&#xff09;和最小公倍数&#xff08;Least Common Multiple&#xff0c;LCM&#xff09; 在C中&#xff0c;可以使用 std::__gcd(a, b)来计算最大公约数 1.欧几里德算法/辗转相除法 int gcd(int a,int b){return b?gcd(b, a%b):a; } 2…

HTML5动画设计工具 Hype 4 Pro v4.1.14中文激活版

Hype Pro是一款功能丰富、易用且灵活的HTML5动画设计工具&#xff0c;适用于设计师、开发者和创作者创建各种精美的交互式网页动画。它的强大功能和可视化编辑界面使用户能够快速而轻松地实现复杂的动画效果&#xff0c;同时支持多种输出格式和交互方式&#xff0c;满足用户对网…

内网安全之-kerberos协议

kerberos协议是由麻省理工学院提出的一种网络身份验证协议&#xff0c;提供了一种在开放的非安全网络中认证识别用户身份信息的方法。它旨在通过使用秘钥加密技术为客户端/服务端应用提供强身份验证&#xff0c;使用kerberos这个名字是因为需要三方的共同参与才能完成一次认证流…

中科驭数DPU技术开放日秀“肌肉”:云原生网络、RDMA、安全加速、低延时网络等方案组团亮相

2024年3月29日&#xff0c;中科驭数以“DPU构建高性能云算力底座”为主题的线上技术开放日活动成功举办。在开放日上&#xff0c;中科驭数集中展现了其在低时延网络、云原生网络及智算中心网络三大关键场景下的技术成果与五大核心DPU解决方案&#xff0c;凸显了中科驭数在高性能…

RDD算子(四)、血缘关系、持久化

1. foreach 分布式遍历每一个元素&#xff0c;调用指定函数 val rdd sc.makeRDD(List(1, 2, 3, 4)) rdd.foreach(println) 结果是随机的&#xff0c;因为foreach是在每一个Executor端并发执行&#xff0c;所以顺序是不确定的。如果采集collect之后再调用foreach打印&#xf…

使用CSS计数器,在目录名称前加上了序号,让目录看起来更加井然有序

目录&#xff08;Text of Contents缩写为TOC&#xff09;&#xff0c;其实就是一篇文章的概要或简述。这好比&#xff0c;去书店买书&#xff0c;先是被这本书的标题所吸引&#xff0c;而后我们才会&#xff0c;翻开这本书目录&#xff0c;看看这本书主要是在讲些什么&#xff…

Claude 3 on Amazon Bedrock 结合多智能体助力 Altrubook AI 定义消费者 AI 新范式

关于 Altrubook AI 智能消费决策机器人 Altrubook 是全球首创场景化智能决策机器人&#xff0c;由国内外大厂等前员工共同研发&#xff0c;具有定制化 IP 决策机器人、沉浸式购物体验和需求匹配优化等独特优势。目前&#xff0c;Altrubook AI 已完成与 Claude 3 on Amazon Bedr…

【深度优先】【树上倍增 】2846. 边权重均等查询

本文涉及知识点 深度优先 树上倍增 LeetCode2846. 边权重均等查询 现有一棵由 n 个节点组成的无向树&#xff0c;节点按从 0 到 n - 1 编号。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges &#xff0c;其中 edges[i] [ui, vi, wi] 表示树中存在一条位于节点 ui…

备战蓝桥杯---贡献法刷题

话不多说&#xff0c;直接看题&#xff1a; 什么是贡献法&#xff1f;这是一种数学思想&#xff0c;就是看每一个元素对总和的贡献。 1. 我们可以先枚举区间再统计次数&#xff0c;但这显然TLE。我们可以发现&#xff0c;每一个孤独的区间对应一个孤独的牛&#xff0c;因此我…

注意力机制篇 | YOLOv8改进之添加多尺度全局注意力机制DilateFormer(MSDA)| 即插即用

前言:Hello大家好,我是小哥谈。多尺度全局注意力机制DilateFormer是一种用图像识别任务的深度学习模型。它是在Transformer模型的基础上进行改进的,旨在提高模型对图像中不同尺度信息的感知能力。DilateFormer引入了多尺度卷积和全局注意力机制来实现多尺度感知。具体来说,…

考古:IT架构演进之IOE架构

考古&#xff1a;IT架构演进之IOE架构 IOE架构&#xff08;IBM, Oracle, EMC&#xff09;出现在20世纪末至21世纪初&#xff0c;是一种典型的集中式架构体系。在这个阶段&#xff0c;企业的关键业务系统往往依赖于IBM的小型机&#xff08;后来还包括大型机&#xff09;、Oracle…

题库管理系统-基于Springboot实现JAVA+SQL离散数学题库管理系统(完整源码+LW+翻译)

基于Springboot实现JAVASQL离散数学题库管理系统(完整源码LW翻译) 概述&#xff1a; 本系统具体完成的功能如下&#xff1a; 1题库的管理与维护&#xff1a;新题的录入&#xff0c;修改&#xff0c;删除等功能。 2生成试卷&#xff1a;包括自动生成与手工改动&#xff0c;要…

ThingsBoaed、系统模块层级讲解

系统管理员能够使用租户配置文件为多个租户配置通用设置。每个租户在单个时间点都拥有唯一的个人资料。 让我们一一查看租户配置文件中的可用设置。 配置文件配置 这些设置允许系统管理员配置对租户创建的实体数量的限制&#xff0c;设置每月最大消息数、API 调用数的限制&…

Vue - 1( 13000 字 Vue 入门级教程)

一&#xff1a;Vue 1.1 什么是 Vue Vue.js&#xff08;通常称为Vue&#xff09;是一款流行的开源JavaScript框架&#xff0c;用于构建用户界面。Vue由尤雨溪在2014年开发&#xff0c;是一个轻量级、灵活的框架&#xff0c;被广泛应用于构建单页面应用&#xff08;SPA&#xf…

java自动化测试学习-03-06java基础之运算符

运算符 算术运算符 运算符含义举例加法&#xff0c;运算符两侧的值相加ab等于10-减法&#xff0c;运算符左侧减右侧的值a-b等于6*乘法&#xff0c;运算符左侧的值乘以右侧的值a*b等于16/除法&#xff0c;运算符左侧的值除以右侧的值a/b等于4%取余&#xff0c;运算符左侧的值除…