力扣198-打家劫舍

news2024/9/21 23:37:21

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

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

示例 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
from typing import List

class Solution:
    def rob(self, nums: List[int]) -> int:
        # 如果房屋数量为 0,直接返回 0,因为没有房子可偷
        if len(nums) == 0:
            return 0
        
        # 如果房屋数量为 1,返回唯一一间房屋的金额
        if len(nums) == 1:
            return nums[0]
        
        # 如果房屋数量为 2,返回两者中较大的金额
        if len(nums) == 2:
            return max(nums[0], nums[1])
        
        # 创建一个 dp 数组,其中 dp[i] 表示偷到第 i 间房屋时能获取的最大金额
        dp = [0] * len(nums)
        
        # 初始化前两间房屋的最大偷窃金额
        dp[0] = nums[0]  # 第一间房屋只能偷它自己
        dp[1] = max(nums[0], nums[1])  # 第二间房屋可以选择偷第一间或第二间,取金额较大者
        
        # 从第 3 间房屋开始,计算每间房屋的最大偷窃金额
        for i in range(2, len(nums)):
            # 对于第 i 间房屋,可以选择:
            # 1. 偷它,并加上偷第 i-2 间房屋的最大金额(因为相邻房屋不能同时偷)
            # 2. 不偷它,直接取第 i-1 间房屋的最大金额
            dp[i] = max(dp[i-2] + nums[i], dp[i-1])
        
        # 返回最后一间房屋对应的最大偷窃金额,即为结果
        return dp[-1]

解释:

  1. 特殊情况处理

    • 如果房屋数量为 0,则返回 0,因为没有房屋可以偷。
    • 如果房屋数量为 1,则返回第一个房屋的金额,因为只能偷这一间。
    • 如果房屋数量为 2,则只能偷其中金额较大的一间,因此返回这两者中的最大值。
  2. 动态规划数组 dp

    • dp[i] 代表到达第 i 间房屋时,小偷能偷到的最大金额。
    • 初始化 dp[0] 为第一个房屋的金额,dp[1] 为前两间房屋中金额较大的值。
  3. 动态规划递推

    • 对于每一间房屋,从第 3 间开始(即下标为 2 的房屋),有两种选择:
      1. 偷这一间房屋,加上第 i-2 间房屋的最大金额。
      2. 不偷这一间房屋,取前一间房屋的最大金额。
    • 在这两者中选择较大的值更新 dp[i],保证每一步都获得最大金额。
  4. 结果返回

    • dp[-1] 即为偷窃到最后一间房屋时的最大金额,也就是最终答案。

dp 是动态规划(Dynamic Programming)的简称,它是一种常见的算法设计思想,用来解决具有重叠子问题和最优子结构的问题。动态规划通过将问题分解为更小的子问题,记录这些子问题的解,然后根据这些子问题的解来构造出原问题的解,从而避免重复计算。

在这个小偷问题中,dp 是一个数组,用来存储每个子问题的最优解,具体来说:

  • dp[i] 表示到达第 i 间房屋时,能够偷到的最大金额。这个数组记录了在每个房屋时,如何做出选择(偷还是不偷),使得偷窃的总金额最大。

动态规划的关键概念:

  1. 重叠子问题: 动态规划适用于那些可以通过递归或分解为相似的子问题解决的情况。比如,在小偷问题中:

    • 如果你决定偷第 i 间房屋,那么你还需要知道偷第 i-2 间房屋能得到的最大金额(因为相邻的房子不能同时偷)。
    • 如果你不偷第 i 间房屋,那么你只需要知道偷第 i-1 间房屋的最大金额。
  2. 最优子结构: 问题的整体最优解可以由其子问题的最优解构成。在这个问题中,偷窃第 i 间房屋的最优解可以通过第 i-2 间房屋和第 i-1 间房屋的最优解推导出来。

举个例子解释 dp 的含义:

假设房屋里的金额是 [2, 7, 9, 3, 1],小偷希望能偷到最多的钱但不能偷相邻的房子。

  • dp[0] = 2:表示只看第 1 间房屋时,最多能偷 2 元。
  • dp[1] = 7:表示只看前两间房屋时,最多能偷 7 元(因为第 2 间房屋钱更多,偷第 1 间房屋不划算)。
  • dp[2] = max(dp[0] + nums[2], dp[1]) = max(2 + 9, 7) = 11:表示到第 3 间房屋时,可以选择偷第 1 间和第 3 间房屋(共 2 + 9 = 11 元),或者只偷前两间房屋(共 7 元),所以偷第 1 和第 3 间房屋的总金额最大。
  • dp[3] = max(dp[1] + nums[3], dp[2]) = max(7 + 3, 11) = 11:到第 4 间房屋时,最优解是保持偷前 3 间房屋的最大金额(11 元),因为偷第 2 间和第 4 间的金额不比之前多。
  • dp[4] = max(dp[2] + nums[4], dp[3]) = max(11 + 1, 11) = 12:到第 5 间房屋时,最优解是偷第 1、3、5 间房屋,总金额为 12 元。

动态规划公式:

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

这个公式的意思是,对于每一间房屋 i,你有两个选择:

  1. 偷它,然后加上两间前房屋(i-2)的最大偷窃金额。
  2. 不偷它,只取前一间房屋(i-1)的最大偷窃金额。

通过这样递推计算,我们可以得出小偷能在不触发警报的情况下,偷窃的最高金额。

总结:

  • dp 是动态规划的核心工具,它用于存储每个子问题的最优解。
  • 动态规划方法通过分解问题,利用以前的结果,避免了重复计算,使得算法更高效。

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

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

相关文章

【读书笔记-《网络是怎样连接的》- 0】全书整体结构

网络是计算机相关课程中的重要部分&#xff0c;更是当今的学习生活中所不可或缺的。虽然相关的经典书籍很多&#xff0c;但是大多数属于深入某一部分的专著&#xff0c;比如TCP/IP协议。像我这样对于网络一知半解的同学来说&#xff0c;更需要一种覆盖网络全貌&#xff0c;每一…

《线性代数》笔记

文章目录 1 行列式1.1 克拉默法则1.2 基本性质1.3 余子式 M i j M_{ij} Mij​1.4 代数余子式 A i j ( − 1 ) i j ⋅ M i j A_{ij} (-1)^{ij} \cdot M_{ij} Aij​(−1)ij⋅Mij​1.5 具体型行列式计算&#xff08;化为基本型&#xff09;1.5.1 主对角线行列式&#xff1a;主…

Python学习——【4.2】数据容器:tuple元组

文章目录 【4.2】数据容器&#xff1a;tuple元组一、元组的定义格式二、元组的特点三、元组的操作&#xff08;一&#xff09;常见操作&#xff08;二&#xff09;循环遍历 【4.2】数据容器&#xff1a;tuple元组 一、元组的定义格式 为什么需要元组 列表是可以修改的。如果想…

seL4 Untyped(二)

链接: Untyped Untyped 这篇主要是针对seL4物理内存管理的介绍。 物理内存 在seL4系统中&#xff0c;除了内核占用的一小部分静态内存之外&#xff0c;其他的所有的物理内存都是用户一级管理的。seL4在启动时创建的对象能力&#xff0c;以及seL4管理的其余物理资源&#xf…

初始网络编程(下)

所属专栏&#xff1a;Java学习 1. TCP 的简单示例 同时&#xff0c;由于 TCP 是面向字节流的传输&#xff0c;所以说传输的基本单位是字节&#xff0c;接受发送都是使用的字节流 方法签名 方法说明 Socket accept() 开始监听指定端口&#xff08;创建时绑定的端口&…

十七、RC振荡电路

振荡电路 1、振荡电路的组成、作用、起振的相位条件以及振荡电路起振和平衡幅度条件&#xff0c; 2、RC电路阻抗与频率、相位与频率的关系曲线; 3、RC振荡电路的相位条件分析和振荡频率

信息安全数学基础(15)欧拉定理

前言 欧拉定理是数论中的一个重要定理&#xff0c;它建立了模运算下指数与模的互质关系。这个定理在密码学、信息安全等领域有着广泛的应用&#xff0c;特别是在公钥密码体制&#xff08;如RSA加密算法&#xff09;中。 一、表述 设 n 是一个正整数&#xff0c;a 是一个与 n 互…

Tomcat服务器—Windows下载配置详细教程

一、关于 1.1 简介 Tomcat是一个开源的Java Servlet容器和Web服务器&#xff0c;由Apache软件基金会维护。它实现了Java Servlet和JavaServer Pages (JSP) 规范&#xff0c;用于运行Java Web应用程序。Tomcat支持多种Java EE功能&#xff0c;并提供了高效的性能和可扩展性&am…

Spring扩展点系列-MergedBeanDefinitionPostProcessor

文章目录 简介源码分析示例示例一&#xff1a;Spring中Autowire注解的依赖注入 简介 spring容器中Bean的生命周期内所有可扩展的点的调用顺序 扩展接口 实现接口ApplicationContextlnitializer initialize AbstractApplicationContext refreshe BeanDefinitionRegistryPos…

记录一个英语听力网站的开发

背景 在当前全球经济衰退的背景下&#xff0c;国内IT相关工作的竞争日益激烈。为了获得更多的职业机会&#xff0c;学习英语或许能为程序员打开一扇新的窗户。尤其是在国际化背景的远程工作中&#xff0c;英语协作沟通是必不可少的。 尽管我们大多数人从小到大都在学习英语&a…

使用Renesas R7FA8D1BH (Cortex®-M85)和微信小程序App数据传输

目录 概述 1 系统架构 1.1 系统结构 1.2 系统硬件框架结构 1.3 蓝牙模块介绍 2 微信小程序实现 2.1 UI介绍 2.2 代码实现 3 上位机功能实现 3.1 通信协议 3.2 系统测试 4 下位机功能实现 4.1 功能介绍 4.2 代码实现 4.3 源代码文件 5 测试 5.1 编译和下载代码…

RNN的反向传播

目录 1.RNN网络&#xff1a;通过时间反向传播(through time back propagate TTBP) 2.RNN梯度分析 2.1隐藏状态和输出 2.2正向传播&#xff1a; 2.3反向传播&#xff1a; 2.4问题瓶颈&#xff1a; 3.截断时间步分类&#xff1a; 4.截断策略比较 5.反向传播的细节 ​编辑…

大数据新视界 --大数据大厂之JavaScript在大数据前端展示中的精彩应用

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

浙大数据结构:05-树8 File Transfer

数据结构MOOC PTA习题 这道题考察并查集的操作&#xff0c;合并以及找根结点 机翻&#xff1a; 1、条件准备 node是数组存放1-N结点的根节点的&#xff0c;n为总结点数 #include <iostream> using namespace std;const int N 1e4 5; int node[N]; int n; 先初始化…

众数信科AI智能体政务服务解决方案——寻知智能笔录系统

政务服务解决方案 寻知智能笔录方案 融合民警口供录入与笔录生成需求 2分钟内生成笔录并提醒错漏 助办案人员二次询问 提升笔录质量和效率 寻知智能笔录系统 众数信科AI智能体 产品亮点 分析、理解行业知识和校验规则 AI实时提醒用户文书需注意部分 全文校验格式、内…

【在Linux世界中追寻伟大的One Piece】进程间关系与守护进程

目录 1 -> 进程组 1.1 -> 什么是进程组 1.2 -> 组长进程 2 -> 会话 2.1 -> 什么是会话 2.2 -> 如何创建会话 2.3 -> 会话ID(SID) 3 -> 控制终端 4 -> 作业控制 4.1 -> 什么是作业(job)和作业控制(Job Control) 4.2 -> 作业号 4.3…

Spring:项目中的统一异常处理和自定义异常

介绍异常的处理方式。在项目中&#xff0c;都会进行自定义异常&#xff0c;并且都是需要配合统一结果返回进行使用。 1.背景引入 &#xff08;1&#xff09;背景介绍 为什么要处理异常&#xff1f;如果不处理项目中的异常信息&#xff0c;前端访问我们后端就是显示访问失败的…

20240921在友善之臂的NanoPC-T6开发板上确认宸芯的数传模块CX6602N的AT命令

console:/dev # cat ttyUSB1 & console:/dev # echo AT > ttyUSB1 20240921在友善之臂的NanoPC-T6开发板上确认宸芯的数传模块CX6602N的AT命令 2024/9/21 21:03 【必须】Android12/Linux&#xff08;Buildroot&#xff09;都必须要&#xff01; 4、【Android12默认打开U…

电脑硬件-机械硬盘

简介 机械硬盘是电脑的主要存储媒介之一&#xff0c;通常用于存储一些文件资料或者学习视频笔记等比较大的内容。 结构 采用磁盘存储数据&#xff0c;使用温彻斯特的结构&#xff0c;特有四个特点&#xff1a; 1.磁头、盘片和运动机构安装在一个密封的腔体内。 2.盘片告诉旋…

一图快速看懂flink source的设计实现

文章目录 整体来说多个处理流程是解偶的&#xff0c;这样可以在面对多数据源情况下&#xff0c;能更加的灵活。 下面只展示了&#xff0c;主要的一些流程 下面补充一点&#xff0c;读取文件状态的保存&#xff0c;切分信息用了一个 ListState 来保存。具体要保存的信息&#x…