当前位置: 首页 > article >正文

LeetCode 热题 100_打家劫舍(83_198_中等_C++)(动态规划)

LeetCode 热题 100_打家劫舍(83_198)

    • 题目描述:
    • 输入输出样例:
    • 题解:
      • 解题思路:
        • 思路一(动态规划(一维dp数组)):
        • 思路二(动态规划(滚动数组)):
      • 代码实现
        • 代码实现(思路一(动态规划(一维dp数组))):
        • 代码实现(思路二(动态规划(滚动数组))):
        • 以思路一为例进行调试

题目描述:

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

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

输入输出样例:

示例 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数组)):

1、解决此问题可以分为4个步骤:
① 定义子问题
② 写出子问题的递推公式
③ 确定DP数组的计算顺序和DP数组的初始化
④ 空间优化(可选)

① 子问题:

  • 当我们偷第i个房间时,则第i-1房间不能偷,i-2和之前的可以偷
  • 当我们不偷第i个房间时,第则i-1和之前的可以偷
  • 我们通过比较偷i房间和不偷i房间的金额来判定当前偷的最大金额
  • f(i)可由f(i-1)和f(i-2)求解

② 通过分析子问题我们自然的能写出递推公式:

  • f(i)=max{f(i-1),f(i-2)+nums[i]},也就是:dp[i]=max{dp[i-1],dp[i-2]+nums[i]}

③ 确定DP数组的计算顺序:

  • 递推公式f(i)可由f(i-1)和f(i-2)求解,所以计算顺序为从左到右顺序进行

④ 空间优化

  • 可通过滚动数组来记录部分DP数组,来进行空间优化


nums=[2,7,9,3,1]
当i=0时,只有一个可偷的房间,dp[0]=2。(dp代表当前下标最多能偷的金额)
当i=1时,可偷2,7两间房中的其中一个(7>2),dp[1]=7
当i=2时, 此时7(nums[1])是否可偷取决于9(nums[2])是否被偷。

  • 当偷nums[2]时,则nums[1]不能偷,nums[1]之前的可以偷,可偷的金额为9+2(dp[0])=11
  • 当不偷nums[2]时,则nums[1]和nums[1]之前的都能偷,可偷金额为7(dp[1])=7
  • 则dp[2]=max(11,7)=11

当i=3时,此时9(nums[2])是否可偷取决于3(nums[3])是否被偷。

  • 当偷nums[3]时,则nums[2]不能偷,nums[2]之前的可以偷,可偷的金额为3+7(dp[1])=10
  • 当不偷nums[3]时,则nums[2]和nums[2]之前的都能偷,可偷金额为11(dp[2])=11
  • 则dp[3]=max(10,11)=11

当i=4时,此时3(nums[3])是否可偷取决于1(nums[4])是否被偷。

  • 当偷nums[4]时,则nums[3]不能偷,nums[3]之前的可以偷,可偷的金额为1+11(dp[2])=12
  • 当不偷nums[4]时,则nums[3]和nums[3]之前的都能偷,可偷金额为11(dp[3])=11
  • 则dp[4]=max(12,11)=11

2、我们通过上述过程总结出,我们将nums[i]偷与不偷分为两种情况:

  • nums[i]偷则nums[i-1]不能偷,此时可偷的金额最大值取决于i-2及之前位置的可偷金额的最大值+nums[i]。
  • nums[i]不偷则nums[i-1]能偷,此时可偷的金额最大值取决于i-1及之前位置的可偷金额的最大值。
  • 通过比较两种情况,确定i位置可偷金额的最大值dp[i]。
  • 我们将每个位置的最大值可偷金额存储在dp[i]中,则会动态的求解出后续位置的最大值可偷金额。

3、复杂度分析:
① 时间复杂度:O(n),其中 n 是数组长度。只需要对数组遍历一次。
② 空间复杂度:O(n),使用dp数组进行记录。

思路二(动态规划(滚动数组)):

1、由思路一可知 dp[i]=max{dp[i-1],dp[i-2]+nums[i]},我们只需维护 dp[i-1] 和 dp[i-2] 两个值就可以。

2、复杂度分析
① 时间复杂度:O(n),其中 n 是数组长度。只需要对数组遍历一次。
② 空间复杂度:O(1),使用滚动数组。

代码实现

代码实现(思路一(动态规划(一维dp数组))):
class Solution1 {
public:int rob(vector<int>& nums) {//dp[i]与dp[i-1]和dp[i-2]相关所以先确定前两项if (nums.size()==0) return 0;if (nums.size()==1) return nums[0];//dp[i]代表当前下标最多能偷的金额vector<int> dp(nums.size());//dp[i]与dp[i-1]和dp[i-2]相关所以先确定前两项dp[0]=nums[0];dp[1]=max(nums[0],nums[1]);//动态的求解其他最多能偷的金额:dp[i]=max{dp[i-1],dp[i-2]+nums[i]}for (int i = 2; i < nums.size(); i++){dp[i]=max(dp[i-2]+nums[i],dp[i-1]);}return dp[nums.size()-1];   }
};
代码实现(思路二(动态规划(滚动数组))):
class Solution2{
public:int rob(vector<int>& nums) {//dp[i]与dp[i-1]和dp[i-2]相关所以先确定前两项if (nums.size()==0) return 0;if (nums.size()==1) return nums[0];//dpi_2代表dp[i-2],dpi_1代表dp[i-1],dpi代表dp[i]int dpi_2=nums[0];int dpi_1=max(nums[0],nums[1]);int dpi=dpi_1;//动态的求解其他最多能偷的金额:dp[i]=max{dp[i-1],dp[i-2]+nums[i]}for (int i = 2; i < nums.size(); i++){dpi=max(dpi_2+nums[i],dpi_1);dpi_2=dpi_1;dpi_1=dpi;}return dpi;   }
};
以思路一为例进行调试
#include<iostream>
#include<vector>
using namespace std;class Solution1 {
public:int rob(vector<int>& nums) {//dp[i]与dp[i-1]和dp[i-2]相关所以先确定前两项if (nums.size()==0) return 0;if (nums.size()==1) return nums[0];//dp[i]代表当前下标最多能偷的金额vector<int> dp(nums.size());//dp[i]与dp[i-1]和dp[i-2]相关所以先确定前两项dp[0]=nums[0];dp[1]=max(nums[0],nums[1]);//动态的求解其他最多能偷的金额:dp[i]=max{dp[i-1],dp[i-2]+nums[i]}for (int i = 2; i < nums.size(); i++){dp[i]=max(dp[i-2]+nums[i],dp[i-1]);}return dp[nums.size()-1];   }
};int main()
{vector<int> nums={1,2,3,1};Solution1 s;cout<<s.rob(nums);return 0;
}

LeetCode 热题 100_打家劫舍(83_198)原题链接
欢迎大家和我沟通交流(✿◠‿◠)

相关文章:

LeetCode 热题 100_打家劫舍(83_198_中等_C++)(动态规划)

LeetCode 热题 100_打家劫舍&#xff08;83_198&#xff09; 题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;思路一&#xff08;动态规划&#xff08;一维dp数组&#xff09;&#xff09;&#xff1a;思路二&#xff08;动态规划&#xff…...

C语言复习--assert断言

assert.h 头⽂件定义了宏 assert() &#xff0c;⽤于在运⾏时确保程序符合指定条件&#xff0c;如果不符合&#xff0c;就报错终止运行。这个宏常常被称为“断⾔”。 assert(p ! NULL); 代码在程序运⾏到这⼀⾏语句时&#xff0c;验证变量 p 是否等于 NULL 。如果确实不等于 NU…...

嵌入式软件设计规范框架(MISRA-C 2012增强版)

以下是一份基于MISRA-C的嵌入式软件设计规范&#xff08;完整技术文档框架&#xff09;&#xff0c;包含编码规范、安全设计原则和工程实践要求&#xff1a; 嵌入式软件设计规范&#xff08;MISRA-C 2012增强版&#xff09; 一、编码基础规范 1.1 文件组织 头文件保护 /* 示…...

系统思考反馈

最近交付的都是一些持续性的项目&#xff0c;越来越感觉到&#xff0c;系统思考和第五项修炼不只是简单的一门课程&#xff0c;它们能真正融入到我们的日常工作和业务中&#xff0c;帮助我们用更清晰的思维方式解决复杂问题&#xff0c;推动团队协作&#xff0c;激发创新。 特…...

【C++】vector常用方法总结

&#x1f4dd;前言&#xff1a; 在C中string常用方法总结中我们讲述了string的常见用法&#xff0c;vector中许多接口与string类似&#xff0c;作者水平有限&#xff0c;所以这篇文章我们主要通过读vector官方文档的方式来学习vector中一些较为常见的重要用法。 &#x1f3ac;个…...

Burpsuite 伪造 IP

可以用于绕过 IP 封禁检测&#xff0c;用来暴力、绕过配额限制。 也可以用来做 ff98sha 出的校赛题&#xff0c;要求用 129 个 /8 网段的 IP 地址访问同一个 domain 插件 - IPRotate 原理&#xff1a;利用云服务商的反向代理服务。把反向代理的域名指向到目标 ip 即可。 http…...

12.小节

1.认识 QLabel 类,能够在界面上显示字符串. 通过 setText 来设置的.参数 QString (Qt 中把 C 里的很多容器类, 进行了重新封装.历史原因&#xff09; c叫法容器类&#xff0c;java叫法集合类 2.内存泄露&#xff0c;文件资源泄露 3.对象树。Qt 中通过对象树,来统一的释放界面的…...

大模型专题10 —LangGraph高级教程:构建支持网页搜索+人工干预的可追溯对话系统

在本教程中,我们将使用 LangGraph 构建一个支持聊天机器人,该机器人能够: ✅ 通过搜索网络回答常见问题 ✅ 在多次调用之间保持对话状态 ✅ 将复杂查询路由给人工进行审核 ✅ 使用自定义状态来控制其行为 ✅ 进行回溯并探索替代的对话路径 我们将从一个基础的聊天机器人开…...

2025年数智化电商产业带发展研究报告260+份汇总解读|附PDF下载

原文链接&#xff1a;https://tecdat.cn/?p41286 在数字技术与实体经济深度融合的当下&#xff0c;数智化产业带正成为经济发展的关键引擎。 从云南鲜花产业带的直播热销到深圳3C数码的智能转型&#xff0c;数智化正重塑产业格局。2023年数字经济规模突破53.9万亿元&#xff…...

Linux中常用服务器监测命令(性能测试监控服务器实用指令)

1.查看进程 ps -ef|grep 进程名以下指令需要先安装:sysstat,安装指令: yum install sysstat2.查看CPU使用情况(间隔1s打印一个,打印6次) sar -u 1 63.#查看内存使用(间隔1s打印一个,打印6次) sar -r 1 6...

SQL:CASE WHEN使用详解

文章目录 1. 数据转换与映射2. 动态条件筛选3. 多条件分组统计4. 数据排名与分级5. 处理空值与默认值6. 动态排序 CASE WHEN 语句在 SQL 中是一个非常强大且灵活的工具&#xff0c;除了常规的条件判断外&#xff0c;还有很多巧妙的用法&#xff0c;以下为你详细总结&#xff1a…...

linux内核`fixmap`和`memblock`有什么不同?

Linux内核中的fixmap和memblock是两个不同层次的内存管理机制&#xff0c;分别用于不同的场景和阶段。以下是它们的核心区别和联系&#xff1a; 功能与作用 memblock 物理内存管理&#xff1a; memblock是内核启动早期的物理内存分配器&#xff0c;在伙伴系统&#xff08;Budd…...

基于 GEE 的区域降水数据可视化:从数据处理到等值线绘制

目录 1 引言 2 代码功能概述 3 代码详细解析 3.1 几何对象处理与地图显示 3.2 加载 CHIRPS 降水数据 3.3 筛选不同时间段的降水数据 3.4 绘制降水时间序列图 3.5 计算并可视化短期和长期降水总量 3.6 绘制降水等值线图 4 总结 5 完整代码 6 运行结果 1 引言 在气象…...

曲线拟合 | Matlab基于贝叶斯多项式的曲线拟合

效果一览 代码功能 代码功能简述 目标&#xff1a;实现贝叶斯多项式曲线拟合&#xff0c;动态展示随着数据点逐步增加&#xff0c;模型后验分布的更新过程。 核心步骤&#xff1a; 数据生成&#xff1a;在区间[0,1]生成带噪声的正弦曲线作为训练数据。 参数设置&#xff1a…...

Qt6调试项目找不到Bluetooth Component蓝牙组件

错误如图所示 Failed to find required Qt component "Bluetooth" 解决方法&#xff1a;搜索打开Qt maintenance tool 工具 打开后&#xff0c;找到这个Qt Connectivity&#xff0c;勾选上就能解决该错误...

JAVA- 锁机制介绍 进程锁

进程锁 基于文件的锁基于Socket的锁数据库锁分布式锁基于Redis的分布式锁基于ZooKeeper的分布式锁 实际工作中都是集群部署&#xff0c;通过负载均衡多台服务器工作&#xff0c;所以存在多个进程并发执行情况&#xff0c;而在每台服务器中又存在多个线程并发的情况&#xff0c;…...

Java Spring Boot 与前端结合打造图书管理系统:技术剖析与实现

目录 运行展示引言系统整体架构后端技术实现后端代码文件前端代码文件1. 项目启动与配置2. 实体类设计3. 控制器设计4. 异常处理 前端技术实现1. 页面布局与样式2. 交互逻辑 系统功能亮点1. 分页功能2. 搜索与筛选功能3. 图书操作功能 总结 运行展示 引言 本文将详细剖析一个基…...

深入剖析JavaScript多态:从原理到高性能实践

摘要 JavaScript多态作为面向对象编程的核心特性&#xff0c;在动态类型系统的支持下展现了独特的实现范式。本文深入解析多态的三大实现路径&#xff1a;参数多态、子类型多态与鸭子类型&#xff0c;详细揭示它们在动态类型系统中的理论基础与实践意义。结合V8引擎的优化机制…...

GalTransl开源程序支持GPT-4/Claude/Deepseek/Sakura等大语言模型的Galgame自动化翻译解决方案

一、软件介绍 文末提供程序和源码下载 GalTransl是一套将数个基础功能上的微小创新与对GPT提示工程&#xff08;Prompt Engineering&#xff09;的深度利用相结合的Galgame自动化翻译工具&#xff0c;用于制作内嵌式翻译补丁。支持GPT-4/Claude/Deepseek/Sakura等大语言模型的…...

TGES 2024 | 基于空间先验融合的任意尺度高光谱图像超分辨率

Arbitrary-Scale Hyperspectral Image Super-Resolution From a Fusion Perspective With Spatial Priors TGES 2024 10.1109/TGRS.2024.3481041 摘要&#xff1a;高分辨率高光谱图像&#xff08;HR-HSI&#xff09;在遥感应用中起着至关重要的作用。单HSI超分辨率&#xff…...

算法基础_基础算法【高精度 + 前缀和 + 差分 + 双指针】

算法基础_基础算法【高精度 前缀和 差分 双指针】 ---------------高精度---------------791.高精度加法题目介绍方法一&#xff1a;代码片段解释片段一&#xff1a; 解题思路分析 792. 高精度减法题目介绍方法一&#xff1a;代码片段解释片段一&#xff1a; 解题思路分析 7…...

多线程猜数问题

题目&#xff1a;线程 A 生成随机数&#xff0c;另外两个线程来猜数&#xff0c;线程 A 可以告诉猜的结果是大还是小&#xff0c;两个线程都猜对后&#xff0c;游戏结束&#xff0c;编写代码完成。 一、Semaphore 多个线程可以同时操作同一信号量&#xff0c;由此实现线程同步…...

Ubuntu环境安装

1. 安装gcc、g和make sudo apt update sudo apt install build-essential 2. 安装cmake ubuntu安装cmake的三种方法&#xff08;超方便&#xff01;&#xff09;-CSDN博客 3. 安装ssh sudo apt-get install libssl-dev...

【家政平台开发(6)】筑牢家政平台安全防线:全方位隐私与安全需求解析

本【家政平台开发】专栏聚焦家政平台从 0 到 1 的全流程打造。从前期需求分析&#xff0c;剖析家政行业现状、挖掘用户需求与梳理功能要点&#xff0c;到系统设计阶段的架构选型、数据库构建&#xff0c;再到开发阶段各模块逐一实现。涵盖移动与 PC 端设计、接口开发及性能优化…...

Python数据类型-list

列表(List)是Python中最常用的数据类型之一&#xff0c;它是一个有序、可变的元素集合。 1. 列表基础 创建列表 empty_list [] # 空列表 numbers [1, 2, 3, 4, 5] # 数字列表 fruits [apple, banana, orange] # 字符串列表 mixed [1, hello, 3.14, True] # 混合类型…...

SpringBoot工程如何考虑优化使其视频请求更流畅

为了优化Spring Boot以提升前端视频读取的流畅性&#xff0c;可以从以下几个关键方向入手&#xff1a; 1. 分块传输与HTTP范围请求&#xff08;Range Requests&#xff09; 视频播放通常需要支持随机跳转进度&#xff0c;需确保后端正确处理HTTP Range头&#xff0c;实现按需传…...

如何使用cpp操作香橙派GPIO --使用<wiringPi.h>

香橙派是国产SBC &#xff0c;对标树莓派。不过国内的开发环境确实挺惨的&#xff0c;没多少帖子讨论。楼主决定从今天起&#xff0c;不定期更新香橙派的教程。 今天的教程是如何使用香橙派下载wiringOP 并使用CPP操作GPIO 操作GPIO 下载wiringPi 检查git 版本克隆wiringPi…...

IP(Internet Protocol,互联网协议)

IP&#xff08;Internet Protocol&#xff0c;互联网协议&#xff09;地址是网络通信的核心标识&#xff0c;其作用可概括为以下关键点&#xff1a; 1. 核心作用 设备唯一标识 为联网设备&#xff08;电脑、手机、服务器等&#xff09;提供全球唯一的逻辑地址&#xff0c;确保数…...

nacos-sdk-go v2.29 中一个拼写错误,我定位了3个小时 ……

文章目录 问题背景问题现象问题定位解决方案经验总结 问题背景 今天在给项目增加服务注册和发现功能时,选择了 nacos 作为服务注册中心。在使用 nacos-sdk-go v2.29 版本进行开发时,遇到了一个令人啼笑皆非的问题,足足花了3个小时才找到原因。 问题现象 在实现服务订阅通知功…...

Linux中的文件寻址

Linux的层级结构 在Linux中一切皆文件 其中 要注意在命令行中看实际选择写哪一种路径 相对路径 绝对路径名称的简写&#xff0c;省略了用户当前所在的系统位置此名称只有在管理当前所在系统目录中子文件时才能使用系统中不以/开有的文件名称都为相对路径在程序操作时会自动…...