代码随想录算法训练营day48|打家劫舍 |198.打家劫舍|213.打家劫舍II|337.打家劫舍 III

news2024/11/17 23:32:07

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数组(dp table)以及下标的含义

dp[i] 下标为i以内的房屋,最多可以偷的金额为dp[i]

2.确定递推公式

决定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房

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

3.初始化

dp[0]=nums[0];

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

4.确定遍历顺序

dp[i] 是根据dp[i - 2] 和 dp[i - 1] 推导出来的,那么一定是从前到后遍历!

5.打印数组

以示例二,输入[2,7,9,3,1]为例。

198.打家劫舍

红框dp[nums.size() - 1]为结果。

代码如下:

class Solution {
    public int rob(int[] nums) {
        int[] dp=new int[nums.length+1];
        dp[0]=nums[0];
        if(nums.length>1){
            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];
    }
}
  • 时间复杂度: O(n)
  • 空间复杂度: O(n)

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

提示:

  • 1 <= nums.length <= 100

  • 0 <= nums[i] <= 1000

  • 思路

首尾连成环了

起点是哪,终点是哪,选不选呢

分情况

  • 考虑不包含首尾元素
  • 考虑首元素
  • 考虑尾元素

后两个情况包含第一个情况

class Solution {
    public int rob(int[] nums) {
        if(nums.length==0) return 0;
        if(nums.length==1) return nums[0];
        int result1=robAction(nums,0,nums.length-2); //考虑首元素
        int result2=robAction(nums,1,nums.length-1);  //考虑尾元素
        return Math.max(result1,result2);

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

337.打家劫舍 III

力扣题目链接

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

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

337.打家劫舍III

  • 思路

后序遍历树,然后按上两题的逻辑

那么下面我以递归三部曲为框架,其中融合动规五部曲的内容来进行讲解

1.确定递归函数的参数和返回值

int[] result=robTree(root)
    

dp[0]表示不偷当前节点得到的最大金钱, dp[1]表示偷当前节点得到的最大金钱

本题dp数组就是一个长度为2的数组!

2.确定终止条件

遇到空节点 偷不偷都是0

int res[] = new int[2];
if(root==null) return res;

这也相当于dp数组的初始化

3.确定遍历顺序

后序遍历

通过递归左节点,得到左节点偷与不偷的金钱。

通过递归右节点,得到右节点偷与不偷的金钱。

int[] left = robAction1(root.left);
int[] right = robAction1(root.right);

4.确定单层递归的逻辑

// 不偷:Max(左孩子不偷,左孩子偷) + Max(又孩子不偷,右孩子偷)
res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
// 偷:左孩子不偷+ 右孩子不偷 + 当前节点偷
res[1] = root.val + left[0] + right[0];
return res;

5.举例推导dp数组

以示例1为例,dp数组状态如下:(注意用后序遍历的方式推导

img

最后头结点就是 取下标0 和 下标1的最大值就是偷得的最大金钱

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

    }
    public int[] robAction(TreeNode root){
        int[] dp=new int[2];
        if(root==null) return dp;

        int[] left=robAction(root.left);
        int[] right=robAction(root.right);
        dp[0]=Math.max(left[0],left[1])+Math.max(right[0],right[1]);
        dp[1]=root.val+left[0]+right[0];
        return dp;
    }
}

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

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

相关文章

Pytorch intermediate(三) BiLSTM

Bi-directional Long Short-Term Memory&#xff0c;双向LSTM网络。 有些时候预测可能需要由前面若干输入和后面若干输入共同决定&#xff0c;这样会更加准确。因此提出了双向循环神经网络&#xff0c;网络结构如上图。 构建LSTM模型时&#xff0c;在参数中添加bidirectionalTr…

面试半个月后的一些想法

源于半个月面试经历后的一些想法&#xff0c;刚开始想的是随便写写&#xff0c;没想到居然写了这么多。 找不到目标找不到意义亦或是烦躁的时候&#xff0c;就写写文章吧&#xff0c;把那些困扰你很久的问题铺开来 花时间仔细想想&#xff0c;其实真正让我们生气懊恼&#xff0…

轻松搭建本地知识库的ChatGLM2-6B

近期发现了一个项目&#xff0c;它的前身是ChatGLM&#xff0c;在我之前的博客中有关于ChatGLM的部署过程&#xff0c;本项目在前者基础上进行了优化&#xff0c;可以基于当前主流的LLM模型和庞大的知识库&#xff0c;实现本地部署自己的ChatGPT&#xff0c;并可结合自己的知识…

华为OD机考算法题:分奖金

题目部分 题目分奖金难度难题目说明公司老板做了一笔大生意&#xff0c;想要给每位员工分配一些奖金&#xff0c;想通过游戏的方式来决定每个人分多少钱。按照员工的工号顺序&#xff0c;每个人随机抽取一个数字。按照工号的顺序往后排列&#xff0c;遇到第一个数字比自己数字…

我们这一代人的机会是什么?

大家好&#xff0c;我是苍何&#xff0c;今天作为专业嘉宾参观了 2023 年中国国际智能产业博览会&#xff08;智博会&#xff09;&#xff0c;是一场以「智汇八方&#xff0c;博采众长」为主题的汇聚全球智能技术和产业创新的盛会&#xff0c;感触颇深&#xff0c;随着中国商业…

在Linux(Centos7)上编译whisper.cpp的详细教程

whisper.cpp的简单介绍&#xff1a; Whisper 是 OpenAI 推出的一个自动语音识别&#xff08;ASR&#xff09;系统&#xff0c;whisper.cpp 则是 Whisper 模型的 C/C 移植。whisper.cpp 具有无依赖项、内存使用量低等特点&#xff0c;支持 Mac、Windows、Linux、iOS 和 Android …

免费开源音乐聚合软件-洛雪音乐助手

一、软件介绍 洛雪音乐助手&#xff08;LX Music&#xff09;&#xff0c;一个基于 Electron Vue 开发的免费开源音乐聚合软件&#xff0c;软件聚合多个音乐平台搜索接口&#xff0c;提供音乐在线播放和下载&#xff0c;而且免费无广告&#xff0c;支持在Windows、Mac OS、L…

CSP 202109-1 数值推导

答题 一眼看上去好像有点复杂&#xff0c;稍微想一下就知道&#xff0c;最大值就是把所有B加起来&#xff0c;最小值就是把不重复的B加起来&#xff0c;用set搞定不重复的元素 #include<iostream> #include<set> using namespace std; int main(){int n,max0,min0…

ARM接口编程—Interrupt(exynos 4412平台)

CPU与硬件的交互方式 轮询 CPU执行程序时不断地询问硬件是否需要其服务&#xff0c;若需要则给予其服务&#xff0c;若不需要一段时间后再次询问&#xff0c;周而复始中断 CPU执行程序时若硬件需要其服务&#xff0c;对应的硬件给CPU发送中断信号&#xff0c;CPU接收到中断信号…

SOC 2.0安全运营中心

SOC&#xff0c;安全运营中心&#xff0c;为取得其最佳效果&#xff0c;以及真正最小化网络风险&#xff0c;需要全员就位&#xff0c;让安全成为每个人的责任。 早在几年前&#xff0c;企业就开始创建SOC来集中化威胁与漏洞的监视和响应。第一代SOC的目标&#xff0c;是集中管…

【使用Cpolar和Qchan搭建自己的个人图床】

文章目录 前言1. Qchan网站搭建1.1 Qchan下载和安装1.2 Qchan网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar云端设置2.2 Cpolar本地设置 3. 公网访问测试总结 前言 图床作为云存储的一项重要应用场景&#xff0c;在大量开发人员的努力下&#xff0c;已经开发出大…

TSMC逻辑制程技术命名和发展

参考来源&#xff1a; 逻辑制程 - 台湾积体电路制造股份有限公司 (tsmc.com) 1、 TSMC逻辑制程发展路线图 2、从65nm到3nm制程技术发展的简介 2.1 65nm 制程 Y2005&#xff1a;成功试产65nm晶片&#xff1b; Y2006&#xff1a;成功通过65nm制程技术的产品验证&#xff0c;推…

asio中的锁

asio到底有没有锁 asio是有锁的&#xff0c;所以规避锁的写法还是值得研究的 windows中的锁 先来张截图&#xff1a; dispatch_mutex_主要是为了保护定时器队列和完成端口回调的队列。 保护定时器队列 保护完成端口回调的队列 在PostQueuedCompletionStatus失败时&#x…

React总结1

3 React技术 React是Facebook于2013年开源的框架。React解决的是前端MVC框架中的View视图层的问题。 3.1 Virtual DOM* DOM&#xff08;文档对象模型Document Object Model&#xff09; 将网页内所有内容映射到一棵树型结构的层级对象模型上&#xff0c;浏览器提供对DOM的支…

构建全面 AI Agent 解决方案:Chocolate Factory 框架的文本到 UI、图表和测试用例生成...

长太不看版&#xff1a;基于领域驱动设计思考的 AI Agent 框架 Chocolate Factory&#xff0c;框架现在还在 PoC 阶段&#xff0c;欢迎加入开发。&#xff08;当前主要关注于 SDLC AIGC 的场景&#xff09;。 GitHub&#xff1a;https://github.com/unit-mesh/chocolate-facto…

MySQL的架构和性能优化

一、架构 MySQL逻辑架构整体分为三层&#xff0c;最上层为客户端&#xff0c;并非MySQL独有&#xff0c;诸如&#xff1a;连接处理&#xff0c;授权认证&#xff0c;安全等功能均在这一层处理 MySQL大多数核心服务均在中间这一层&#xff0c;包括查询解析&#xff0c;分析优化…

【Mysql】数据库第三讲(表的约束、基本查询语句)

表的约束和基本查询 1.表的约束1.1 空属性1.2默认值1.3列描述1.4 zerofill1.5主键1.6 自增长1.7 唯一键1.8外键 1.表的约束 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c; 需要有一些额外的约束&#xff0c; 更好的保证数据的合法性&#xff0c;从…

【Flowable】FlowableUI使用以及在IDEA使用flowable插件(二)

前言 之前有需要使用到Flowable&#xff0c;鉴于网上的资料不是很多也不是很全也是捣鼓了半天&#xff0c;因此争取能在这里简单分享一下经验&#xff0c;帮助有需要的朋友&#xff0c;也非常欢迎大家指出不足的地方。 一、部署FlowableUI 1.准备war包 在这里提供了&#xf…

Java之Hashset的原理及解析

4.数据结构 4.1二叉树【理解】 二叉树的特点 二叉树中,任意一个节点的度要小于等于2 节点: 在树结构中,每一个元素称之为节点 度: 每一个节点的子节点数量称之为度 二叉树结构图 4.2二叉查找树【理解】 二叉查找树的特点 二叉查找树,又称二叉排序树或者二叉搜索树 每一…