【LeetCode】动态规划—打家劫舍(附完整Python/C++代码)

news2024/11/15 23:39:56

动态规划—#198. 打家劫舍

  • 前言
  • 题目描述
  • 基本思路
    • 1. 问题定义:
    • 2. 理解问题和递推关系:
    • 3. 解决方法:
    • 4. 进一步优化:
    • 5. 小总结:
  • 代码实现
    • Python3代码实现
    • Python 代码解释
    • C++代码实现
    • C++ 代码解释
  • 总结:

前言

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

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

题目描述

在这里插入图片描述

基本思路

1. 问题定义:

你是一个小偷,计划偷窃沿街的房屋,每个房屋里都有一定数量的现金。由于房屋之间装有警报器,如果你偷了相邻的两家,那么警报就会响。因此,你需要设计一个策略,确保不触发警报器的情况下,偷到最多的现金。

给定一个数组 n u m s [ ] nums[] nums[],其中 n u m s [ i ] nums[i] nums[i] 表示第 i i i 个房屋中的现金数,你需要返回你在不触发警报的前提下能偷窃到的最高金额。

2. 理解问题和递推关系:

  • 对于每一个房子,你有两种选择:
  1. 偷这个房子,那么你就不能偷前一个房子,只能考虑前 i − 2 i-2 i2 个房子的收益。
  2. 不偷这个房子,那么你可以选择偷或不偷前一个房子的最大收益。
  • 这给了我们一个递推关系式:

d p [ i ] = max ⁡ ( d p [ i − 1 ] , d p [ i − 2 ] + nums ⁡ [ i ] ) d p[i]=\max (d p[i-1], d p[i-2]+\operatorname{nums}[i]) dp[i]=max(dp[i1],dp[i2]+nums[i])

其中 d p [ i ] dp[i] dp[i] 表示偷到第 i i i 个房子时的最大金额。

3. 解决方法:

  1. 初始条件:如果只有一个房子,那么结果是 n u m s [ 0 ] nums[0] nums[0];如果有两个房子,结果是 m a x ( n u m s [ 0 ] , n u m s [ 1 ] ) max(nums[0], nums[1]) max(nums[0],nums[1])
  2. 递推公式:对于第 i i i 个房子,偷或不偷的最大金额为 d p [ i ] = max ⁡ ( d p [ i − 1 ] , d p [ i − 2 ] + d p[i]=\max (d p[i-1], d p[i-2]+ dp[i]=max(dp[i1],dp[i2]+ nums[i])。
  3. 目标:计算出最后一个房子 d p [ n − 1 ] d p[n-1] dp[n1] ,即偷窃到最后一个房子的最大金额。

4. 进一步优化:

在递推过程中,我们注意到每次计算 d p [ i ] d p[i] dp[i] 只依赖于 d p [ i − 1 ] d p[i-1] dp[i1] d p [ i − 2 ] d p[i-2] dp[i2] ,因此我们可以使用两个变量来代替整个 d p [ ] d p[] dp[] 数组,节省空间。

  • 时间复杂度: O ( n ) O(n) O(n) ,只需要遍历一次数组。
  • 空间复杂度: O ( 1 ) O(1) O(1) ,只使用常量空间。

5. 小总结:

  • 递推思路:每个房子有偷或不偷两种选择,偷当前房子的话要加上前 i − 2 i-2 i2 个房子的收益,不偷的话则直接沿用前一个房子的最大收益。
  • 优化:通过只使用两个变量存储前面的结果,可以将空间复杂度优化为 O ( 1 ) O(1) O(1)
  • 目标是找到通过递推公式,偷窃到最后一个房子的最大金额。

以上就是打家劫舍问题的基本思路。

代码实现

Python3代码实现

class Solution:
    def rob(self, nums: list[int]) -> int:
        # 边界情况处理:如果房子数量为0或1
        if not nums:
            return 0
        elif len(nums) == 1:
            return nums[0]
        
        # 初始化前两个房子的最大收益
        prev2 = 0  # 表示前两个房子的收益
        prev1 = nums[0]  # 表示前一个房子的收益
        
        # 从第三个房子开始计算到最后一个房子
        for i in range(1, len(nums)):
            # 当前房子的最大收益为:偷前两个房子加当前房子的收益,或者不偷这个房子,延续前一个房子的收益
            current = max(prev1, prev2 + nums[i])
            # 更新前两个房子的最大收益
            prev2 = prev1
            prev1 = current
        
        # 最终返回偷窃到最后一个房子的最大收益
        return prev1

Python 代码解释

  1. Base Case:处理只有一个房子或者没有房子的情况。
  2. 动态规划:使用 p r e v 2 prev2 prev2 p r e v 1 prev1 prev1 来存储偷前两个房子和前一个房子的最大收益,然后依次更新。
  3. 最终结果:返回最后一个房子的最大收益。

C++代码实现

class Solution {
public:
    int rob(vector<int>& nums) {
        // 边界情况处理:如果房子数量为0或1
        if (nums.empty()) return 0;
        if (nums.size() == 1) return nums[0];
        
        // 初始化前两个房子的最大收益
        int prev2 = 0;  // 表示前两个房子的收益
        int prev1 = nums[0];  // 表示前一个房子的收益
        
        // 从第三个房子开始计算到最后一个房子
        for (int i = 1; i < nums.size(); ++i) {
            // 当前房子的最大收益为:偷前两个房子加当前房子的收益,或者不偷这个房子,延续前一个房子的收益
            int current = max(prev1, prev2 + nums[i]);
            // 更新前两个房子的最大收益
            prev2 = prev1;
            prev1 = current;
        }
        
        // 最终返回偷窃到最后一个房子的最大收益
        return prev1;
    }
};

C++ 代码解释

  1. Base Case:处理只有一个房子或者没有房子的情况。
  2. 动态规划:使用 prev2 和 prev1 变量,依次更新每个房子偷窃的最大收益。
  3. 最终结果:返回最后一个房子的最大收益。

总结:

  • 递推公式: d p [ i ] = max ⁡ ( d p [ i − 1 ] , d p [ i − 2 ] + d p[i]=\max (d p[i-1], d p[i-2]+ dp[i]=max(dp[i1],dp[i2]+ nums[i]),通过选择偷或不偷当前房子,来最大化收益。
  • 空间优化:将空间复杂度优化为 O ( 1 ) O(1) O(1) ,通过两个变量 prev1 和 prev2 存储前两个房子的最大收益。
  • 时间复杂度: O ( n ) O(n) O(n) ,只需遍历一次数组。

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

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

相关文章

JinDouYun性能测试工具使用方法

1.功能介绍 2. 安卓端支持安卓6及以上的版本&#xff0c;ios支持大部分版本 3. 可以测试游戏&#xff0c;视频&#xff0c;普通应用的性能数据&#xff0c;数据精准&#xff0c;低延迟&#xff0c;无侵入 4.工具下载链接 筋斗云 5.后续功能添加&#xff0c;高版本支持&…

网页爬虫法律与道德:探索法律边界与道德规范

目录 引言 一、网络爬虫技术概述 1.1 定义与功能 1.2 技术原理 1.3 案例分析 二、网络爬虫的法律边界 2.1 合法性要求 2.2 刑事风险 2.3 案例分析 三、网络爬虫的道德规范 3.1 尊重版权和隐私 3.2 合理使用爬虫技术 3.3 透明度和社会责任 四、技术挑战与应对策略…

[linux 驱动]块设备驱动详解与实战

目录 1 描述 2 结构体 2.1 block_device_operations 2.2 gendisk 2.3 block_device 2.4 request_queue 2.5 request 2.6 bio 3.7 blk_mq_tag_set 3.8 blk_mq_ops 3 相关函数 3.1 注册注销块设备 3.1.1 register_blkdev 3.1.2 unregister_blkdev 3.2 gendisk 结构…

SpringBoot开发——整合Hutool工具类轻松生成验证码

文章目录 1、Hutool简介2、验证码效果展示2.1 扭曲干扰验证码2.2 线条干扰验证码2.3 圆圈干扰验证码3、验证码应用场景3.1. 用户注册与身份验证3.2. 支付验证3.3. 订单与物流通知3.4. 信息安全与隐私保护3.5. 通知与提醒3.6. 其他应用场景4、Hutool工具类实现验证码生成4.1 引入…

如何使用ssm实现基于VUE的儿童教育网站的设计与实现+vue

TOC ssm676基于VUE的儿童教育网站的设计与实现vue 第一章 课题背景及研究内容 1.1 课题背景 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全…

API公共开放平台设计

背景 随着业务发展未来会有更多的三方应用接入公司平台,目前为服务商定制的机制无法满足三方应用快速接入,所以需要一个更加通用的解决方案,开放平台势在必行。 目标 设计一套通用协议,可以支持其他应用快速接入。 说明 本方案旨在设计整体架构,以及对为何这样设计做…

React 理解 re-render 的作用、概念,并提供详细的例子解释

一、什么是 re-render 在 React 中 re-render&#xff08;重新渲染&#xff09; 是经常发生的行为&#xff0c;主要确保视图要时刻保持最新的数据来呈现。 但每次发生 re-render 也是有代价的&#xff0c;比如数据状态、focus 焦点、表单数据、都得重置&#xff0c; 遇到代码…

获取商品销量详情API:深入解析返回值,助力电商决策

在电商行业&#xff0c;了解商品的销量详情对于商家制定营销策略、优化库存管理和提升用户体验至关重要。通过调用获取商品销量详情的API接口&#xff0c;商家可以实时获取关键的销售数据&#xff0c;从而做出更加明智的决策。本文将深入解析获取商品销量详情API的返回值&#…

linux信号| 学习信号三步走 | 学习信号需要打通哪些知识脉络?

前言: 本节内容主要讲解linux下信号的预备知识以及信号的概念&#xff0c; 信号部分我们将会分为几个阶段进行讲解&#xff1a;信号的概念&#xff0c; 信号的产生&#xff0c; 信号的保存。本节主要讲解信号 ps:本节内容适合学习了进程相关概念的友友们进行观看哦 目录 什么是…

轻松重置 MySQL 8.0 Root 密码的简便方法!

在Windows环境下安装MySQL数据后&#xff0c;如果忘记了 MySQL 8.0 的 root 密码&#xff0c;不必担心&#xff01;通过 --skip-grant-tables 和 named-pipe 模式登录后&#xff0c;只需几步简单的 SQL 命令即可重置密码&#xff1a;刷新权限表、修改密码、再刷新权限&#xff…

SpringBoot+Thymeleaf租房管理系统

> 这是一个基于SpringBootThymeleafBootstrap实现的租房管理系统。 > 功能比较完善&#xff0c;包括用户注册/登录、房源登记、账单费用配置、统计报告等功能。 > 模拟真实使用环境&#xff0c;包括了自然人与法人的身份证明录入、房产证信息录入、通过邮件推送月…

E2VPT: An Effective and Efficient Approach for Visual Prompt Tuning

论文汇总 存在的问题 1.以前的提示微调方法那样只关注修改输入&#xff0c;而应该明确地研究在微调过程中改进自注意机制的潜力&#xff0c;并探索参数效率的极限。 2.探索参数效率的极值来减少可调参数的数量? 解决办法 提示嵌入进行transformer中 提示剪枝 Token-wise …

学生网上选课系统设计与实现

学生网上选课系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装学生网上选课系统软件来发挥其…

托盘检测系统源码分享

托盘检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

两数之和、三数之和、四数之和

目录 两数之和 题目链接 题目描述 思路分析 代码实现 三数之和 题目链接 题目描述 思路分析 代码实现 四数之和 题目链接 题目描述 思路分析 代码实现 两数之和 题目链接 LCR 179. 查找总价格为目标值的两个商品 - 力扣&#xff08;LeetCode&#xff09; 题目…

牛客周赛 Round 61 (C++实现)

比赛链接&#xff1a;牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com) 文章目录 1.致十年后的我们1.1 题目描述1.2 思路1.3 代码 2.简单图形问题2.1 题目描述2.2 思路2.3 代码 3. 小红的机器人构造3.1 题目描述3.2 思路3.2.1 问题13.2.2 问题23…

力扣 中等 1901.寻找峰值II

文章目录 题目介绍题解 题目介绍 题解 需要明白一个事实&#xff1a;从任意一个点出发&#xff0c;可以经过一个递增路径&#xff0c;找到一个极大值点。 求出一行的最大值&#xff0c;如果这行最大值比上面的要小&#xff0c;那峰值&#xff08;之一&#xff09;就会在上面 …

最具成长潜力奖!2024中国互联网发展创新与投资大赛(深圳)落幕,爱加密载誉而归!

近日&#xff0c;由中央网信办信息化发展局、广东省委网信办指导&#xff0c;中国互联网发展基金会、中国互联网投资基金、深圳市委网信办联合主办的2024中国互联网发展创新与投资大赛&#xff08;深圳&#xff09;正式落幕。 本次大赛共有508个项目报名参赛&#xff0c;经过4个…

springboot中的异步任务

在springboot项目中可以通过EnableAsyncAsync的方式简化异步操作&#xff0c;下文使用springboot:3.2.1 源码分析 若一个bean中的公共方法上标注了Async&#xff0c;在系统启动时&#xff0c;会给这个类创建一个代理对象&#xff0c;并将该代理对象作为bean注册到spring容器中 …

PyTorch 模型调试与故障排除指南

在当代深度学习领域&#xff0c;PyTorch 已成为开发和训练神经网络的主要框架之一。然而随着模型复杂度的增加和数据规模的扩大&#xff0c;开发者常常面临各种调试和优化挑战。本文旨在为 PyTorch 开发者提供一个全面的调试指南&#xff0c;涵盖从基础概念到高级技术的广泛内容…