算法学习——LeetCode力扣动态规划篇5(198. 打家劫舍、213. 打家劫舍 II、337. 打家劫舍 III )

算法学习——LeetCode力扣动态规划篇5

在这里插入图片描述

198. 打家劫舍

198. 打家劫舍 - 力扣(LeetCode)

描述

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

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

示例

示例 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[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]

dp[i]取最大值,即dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);

class Solution {
public:int rob(vector<int>& nums) {if(nums.size()==1) return nums[0];else if(nums.size()==2) return max(nums[0],nums[1]);vector<int> dp(nums.size() , 0);dp[0]=nums[0];dp[1]=max(nums[0],nums[1]);for(int i=2 ; i<nums.size() ;i++){dp[i] = max( dp[i-1] , dp[i-2] + nums[i]);}return dp[nums.size()-1];}
};

213. 打家劫舍 II

213. 打家劫舍 II - 力扣(LeetCode)

描述

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

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

示例

示例 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 = [1,2,3]
输出:3

提示

1 <= nums.length <= 100
0 <= nums[i] <= 1000

代码解析

其实就是把环拆成两个队列,一个是从0到n-1,另一个是从1到n,然后返回两个结果最大的。

class Solution {
public:int robRange(vector<int>& nums, int start, int end) {if((end - start) == 1 ) return nums[start];if((end - start) == 2) return max(nums[start],nums[start+1]);vector<int> dp((end - start) , 0);dp[0] = nums[start];dp[1] = max(nums[start],nums[start+1]);for(int i=2 ; i<(end - start) ;i++){dp[i] = max(dp[i-1],dp[i-2]+nums[start+i]);}// for(auto it:dp) cout<<it<<' ';// cout<<endl;return dp[end-start-1];}int rob(vector<int>& nums) {if(nums.size()==0) return 0;if(nums.size()==1) return nums[0];int result1 = robRange(nums,0,nums.size()-1);int result2 = robRange(nums,1,nums.size());// cout<<result1<<' '<<result2;return max(result1,result2);}
};

337. 打家劫舍 III

337. 打家劫舍 III - 力扣(LeetCode)

描述

小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。

除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。

给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。

示例

示例 1:
在这里插入图片描述

输入: root = [3,2,3,null,3,null,1]
输出: 7
解释: 小偷一晚能够盗取的最高金额 3 + 3 + 1 = 7
示例 2:

在这里插入图片描述

输入: root = [3,4,5,1,3,null,1]
输出: 9
解释: 小偷一晚能够盗取的最高金额 4 + 5 = 9

提示

树的节点数在 [1, 104] 范围内
0 <= Node.val <= 104

代码解析

动态规划

返回数组就是dp数组。

  • 下标为0记录:不偷该节点所得到的的最大金钱
  • 下标为1记录:偷该节点所得到的的最大金钱。
    在遍历的过程中,如果遇到空节点的话,无论偷还是不偷都是0,

首先明确的是使用后序遍历。 因为通过递归函数的返回值来做下一步计算。

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

单层递归的逻辑

  • 如果是偷当前节点,那么左右孩子就不能偷,
    val1 = cur->val + left[0] + right[0]; (

  • 如果不偷当前节点,那么左右孩子就可以偷,至于到底偷不偷一定是选一个最大的
    val2 = max(left[0], left[1]) + max(right[0], right[1]);

  • 最后当前节点的状态就是{val2, val1};
    即:{不偷当前节点得到的最大金钱,偷当前节点得到的最大金钱}

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public://返回数组。0是不偷,1是偷vector<int> backtracking(TreeNode* cur){//空节点,偷和不偷都是0if(cur == nullptr )return vector<int>(2,0);vector<int> left = backtracking(cur->left);vector<int> right = backtracking(cur->right);//不偷,在左右子节点选最大的int val0 = max(left[0],left[1]) + max(right[0] , right[1]);//偷,当前节点加上左右不偷int val1 = cur->val + left[0] + right[0];return vector<int>{val0 ,val1};}int rob(TreeNode* root) {vector<int> result =  backtracking(root);//偷和不偷选最大return max(result[0],result[1]);}
};
回溯
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int result = 0;unordered_map<TreeNode* , int> my_map;int trak_back(TreeNode* cur){if(cur == nullptr) return 0;if(my_map[cur] != 0) return my_map[cur];else if(cur->left==nullptr && cur->right==nullptr) return cur->val;int value = cur->val;if(cur->left != nullptr ) value += trak_back(cur->left->left) + trak_back(cur->left->right);if(cur->right != nullptr ) value += trak_back(cur->right->left) + trak_back(cur->right->right);my_map[cur] = max( value , trak_back(cur->left) + trak_back(cur->right));return my_map[cur];}int rob(TreeNode* root) {return trak_back(root);}
};
树形递归
/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector<int> track_back(TreeNode* cur){if(cur == nullptr) return {0,0};vector<int> dp(2,0);vector<int> left_dp = track_back(cur->left);vector<int> right_dp = track_back(cur->right);//不偷当前节点,左右节点可偷可不偷,选大的dp[0] = max(left_dp[0],left_dp[1]) + max(right_dp[0],right_dp[1]);//偷当前节点dp[1] = cur->val + left_dp[0] + right_dp[0];return dp;}int rob(TreeNode* root) {//dp[0]为当前节点不偷的值,dp[1]为偷vector<int> dp = track_back(root);return max(dp[0] , dp[1]);}
};

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在jupyter使用新建的虚拟环境以及改变jupyter启动文件路径。

对于刚刚使用jupyter的新手来说&#xff0c;经常不知道如何在其中使用新建的虚拟环境内核&#xff0c;同时&#xff0c;对于默认安装的jupyter&#xff0c;使用jupyter notebook命令启动 jupyter 以后往往默认是C盘的启动路径&#xff0c;如下图所示&#xff0c;这篇教程将告诉…

如何使用 ChatGPT 进行编码和编程

文章目录 一、初学者1.1 生成代码片段1.2 解释功能 二、自信的初学者2.1 修复错误2.2 完成部分代码 三、中级水平3.1 研究库3.2 改进旧代码 四、进阶水平4.1 比较示例代码4.2 编程语言之间的翻译 五、专业人士5.1 模拟 Linux 终端 总结 大多数程序员都知道&#xff0c;ChatGPT …

server端

一、创建项目 expess server 1.1 安装nodemon npm i nodemon 1.2 设置连接数据库mongodb 安装mongoose npm i mongoose 在根目录新建config文件夹/db.config.js // 引入mongodb数据库操作模块 const mongoose require("mongoose") // 连接数据库mongoose.con…

【力扣刷题日记】1173.即时食物配送I

前言 练习sql语句&#xff0c;所有题目来自于力扣&#xff08;https://leetcode.cn/problemset/database/&#xff09;的免费数据库练习题。 今日题目&#xff1a; 1173.即时食物配送I 表&#xff1a;Delivery 列名类型delivery_idintcustomer_idintorder_datedatecustomer…

软件杯 深度学习YOLOv5车辆颜色识别检测 - python opencv

文章目录 1 前言2 实现效果3 CNN卷积神经网络4 Yolov56 数据集处理及模型训练5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习YOLOv5车辆颜色识别检测 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0…

cesium加载.tif格式文件

最近项目中有需要直接加载三方给的后缀名tif格式的文件 <script src"https://cdn.jsdelivr.net/npm/geotiff"></script> 或者 yarn add geotiff npm install geotiff 新建tifs.js import GeoTIFF, { fromBlob, fromUrl, fromArrayBuffer } from geotif…

LabVIEW车载轴承振动监测系统

LabVIEW车载轴承振动监测系统 随着汽车工业的快速发展&#xff0c;车用轴承的稳定性和可靠性对保障车辆安全运行越来越重要。目前&#xff0c;大多数车用轴承工作在恶劣的环境下&#xff0c;容易出现各种故障。开发了一种基于LabVIEW的车载轴承振动监测系统&#xff0c;提高车…

【Linux】详解文件系统以及周边知识

一、磁盘的基本知识 磁盘中可以被划分成一个一个的环&#xff0c;每个环都是一个磁道。每个磁道又可以被均分成一个一个的扇区&#xff0c;扇区是磁盘IO的基本单位&#xff08;想要修改扇区中的一个比特位就必须把该扇区的全部比特位都加载到内存中&#xff09;。磁盘中的盘面&…

Linux进程间通信

文章目录 进程通信管道无名管道有名管道 信号通信kill、raise、alarmsignal 处理信号采用信号方式的进程间通信 共享内存shmget 创建ftok 创建key值shmat 映射地址shmdt/shmctl 删除采用共享内存方式的进程间通信 消息队列msgget 创建msgctl 删除msgsnd 发送消息msgrcv 接收消息…

C语言之动态内存管理

在C语言中我们在栈上开辟的空间是固定的&#xff0c;一旦确定好大小就不能随意改变&#xff0c;就想你创建了 int i 10; int arr[10] {0}; int i 一旦确定下来就是四个字节&#xff0c;arr一旦确定好大小在重新运行时也是不能改变的。 为此C语言引入了动态内存空间开辟&#…

java算法day39 | 动态规划part02 ● 62.不同路径 ● 63. 不同路径 II

62.不同路径 思路&#xff1a; 本题非常巧妙。 第一步&#xff1a;定义一个dp数组存储到达每个位置的路径数。 第二步&#xff1a;每个位置的路径数它左面位置的路径数上面位置的路径数。 第三步&#xff1a;不好想的是如何初始化数组。 既然只能向下或向右走&#xff0c;可推出…

全局UI方法-弹窗三-文本滑动选择器弹窗(TextPickDialog)

1、描述 根据指定的选择范围创建文本选择器&#xff0c;展示在弹窗上。 2、接口 TextPickDialog(options?: TextPickDialogOptions) 3、TextPickDialogOptions 参数名称 参数类型 必填 参数描述 rang string[] | Resource 是 设置文本选择器的选择范围。 selected nu…

C易错注意之分支循环,悬空else,短路表达式,static

接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗-----------林辞忧 前言&#xff1a; c语言中一些关于分支循环中continue常混淆&#xff0c;悬空esle问题&#xff0c;短路表达式&#xff0c;static ,extern在使用时稍不注意就会出错的点,接下来我们将介绍…

javaWeb项目-学生考勤管理系统功能介绍

项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#xff1a;Vue、ElementUI 关键技术&#xff1a;springboot、SSM、vue、MYSQL、MAVEN 数据库工具&#xff1a;Navicat、SQLyog 1、JAVA技术 JavaSc…

Bat中cd到中文路径报错以及windows上设置快捷方式延迟启动执行

场景 要实现在windows启动目录下&#xff0c;执行bat脚本文件。 脚本文件中需要进入某个中文目录 所以直接 cd /d D:\test\中文路径 start test.bat 此时会提示&#xff1a; 此时需要指定bat的编码方式&#xff0c;修改bat脚本文件&#xff0c;添加如下 chcp 65001 cd /d…

AI预测福彩3D第22弹【2024年3月31日预测--第5套算法开始计算第4次测试】

今天&#xff0c;咱们继续进行本套算法的测试&#xff0c;今天为第四次测试&#xff0c;仍旧是采用冷温热趋势结合AI模型进行预测。好了&#xff0c;废话不多说了。直接上结果~ 仍旧是分为两个方案&#xff0c;1大1小。 经过人工神经网络计算并进行权重赋值打分后&#xff0c;3…

通过WSL在阿里云上部署Vue项目

参考&#xff1a; 阿里云上搭建网站-CSDN博客 云服务器重装 关闭当前运行实例 更换操作系统&#xff0c;还有其他的进入方式。 选择ubuntu系统&#xff08;和WSL使用相同的系统&#xff09;。 设置用户和密码。发送短信验证码。 新系统更新。秒速干净的新系统设置完成。 这…

国内ip切换app,让切换ip变得简单

在数字化快速发展的今天&#xff0c;互联网已经成为我们生活中不可或缺的一部分。然而&#xff0c;随着网络应用的深入&#xff0c;用户对于网络环境的需求也日益多样化。其中&#xff0c;IP地址作为网络中的关键标识&#xff0c;其切换与管理显得尤为重要。为了满足用户对于IP…

MongoDB副本集环境搭建(以单机Windows为例)

前言 近期有搭建MongoDB副本集的需求,简单记录一下搭建过程(以本地Windows环境为例)。 一、副本集选型 1 Primary节点、1 Secondary 节点、1 Arbiter节点模式副本集环境搭建。 二、搭建过程 1. 安装MongoDB服务 下载地址:https://www.mongodb.com,如下图所示: 选择…

element表格 加滚动,监听底部实现分页加载

表格要实现滚动很简单&#xff0c;给他加一个高度即可 height"300" 然后是监听事件 mounted() {this.lazyLoading();}, methods:{lazyLoading(){let dom document.querySelector(".el-table__body-wrapper");dom.addEventListener("scroll", (…