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

算法学习——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.mzph.cn/news/782441.shtml

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

相关文章

python学习16:python中的布尔类型和条件语句的学习

python中的布尔类型和条件语句的学习 1.布尔&#xff08;bool&#xff09;类型的定义&#xff1a; 布尔类型的字面量&#xff1a;True表示真&#xff08;是、肯定&#xff09; False表示假&#xff08;否、否定&#xff09; True本质上是一个数字记作1&#xff0c;False记作0 …

遥感数字图像处理的学习笔记

相关链接&#xff1a; 遥感数字图像处理实验教程&#xff08;韦玉春&#xff09;--部分实验问题回答 目录 1.什么是图像&#xff0c;什么是数字图像&#xff1f; 2.什么是遥感数字图像&#xff1f;模拟图像(照片)与遥感数字图像有什么区别&#xff1f; 3.什么是遥感数字图像…

构建操作可靠的数据流系统

文章目录 前言数据流动遇到的困难先从简单开始可靠性延迟丢失 性能性能损失性能——分层重试 可扩展性总结 前言 在流式架构中&#xff0c;任何对非功能性需求的漏洞都可能导致严重后果。如果数据工程师没有将可伸缩性、可靠性和可操作性等非功能性需求作为首要考虑因素来构建…

智慧公厕的全域感知、全网协同、全业务融合和全场景智慧赋能

公共厕所是城市的重要组成部分&#xff0c;为市民提供基本的生活服务。然而&#xff0c;传统的公厕管理模式存在诸多问题&#xff0c;如排队等候时间长、卫生状况差、空气质量差等&#xff0c;严重影响市民的出行和生活质量。为了解决这些问题&#xff0c;智慧公厕应运而生&…

【Python基础教程】4 . 算法的空间复杂度

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;python基础教程 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、…

最短路-Floyd Dijkstrea

Floyd算法 一种求解“多源最短路”问题的算法 在Floyd算法中&#xff0c;图一般用邻接矩阵存储&#xff0c;边权可正可负&#xff08;但不允许负环&#xff09;&#xff0c;利用动态规划的思想&#xff0c;逐步求解出任意两点之间的最短距离 int d[N][N],初始为无穷 d[i][j…

拌合楼管理软件开发(十三) 对接耀华XK3190-A9地磅(实战篇)

前言: 实战开整 目前而言对于整个拌合楼管理软件开发,因为公司对这个项目还处于讨论中,包括个人对其中的商业逻辑也存在一些质疑,都是在做一些技术上的储备.很早就写好了串口与地磅对接获取代码,也大概知道真个逻辑,这次刚好跟库区沟通,远程连接到磅房电脑,开始实操一下. 一、地…

【C++】反向迭代器

一、前言 在前面对vector等容器的学习中&#xff0c;我们学会了如何去使用正向迭代器并模拟实现 但是我们没有去模拟实现反向迭代器&#xff0c;这篇文章中我们就来了解反向迭代器的底层并实现它&#xff0c;把之前的坑给填上。 二、反向迭代器 反向迭代器的底层设计十分精妙…

python统计分析——灵敏度、特异度和ROC曲线

参考资料&#xff1a;python统计分析【托马斯】 1、灵敏度和特异度 灵敏度&#xff1a;也叫作效能。被检验正确识别出来的阳性结果&#xff08;病人中有疾病且检验结果是阳性的概率&#xff09;。 特异度&#xff1a;被检验正确识别出来的阴性结果&#xff08;病人健康且检验结…

大模型融合方法-DARE

LLM在SFT之后会产生大量的冗余参数(delta参数)&#xff0c;阿里团队提出DARE方法来消除delta参数&#xff0c;并将其合并到PRE模型中&#xff0c;从而实现多源模型能力的吸收。 DARE无需GPU重新训练&#xff0c;其思路非常简单&#xff0c;就跟dropout类似&#xff1a; m t ∼…

针对pycharm打开新项目需要重新下载tensorflow的问题解决

目录 一、前提 二、原因 三、解决办法 一、前提 下载包之前&#xff0c;已经打开了&#xff0c;某个项目。 比如&#xff1a;我先打开了下面这个项目&#xff1a; 然后在terminal使用pip命令下载&#xff1a; 如果是这种情况&#xff0c;你下载的这个包一般都只能用在这一个…

自动驾驶轨迹规划之时空语义走廊(一)

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 目录 1.摘要 2.系统架构 3.MPDM 4.时空语义走廊 ​4.1 种子生成 4.2 具有语义边界的cube inflation ​4.3 立方体松弛 本文解析了丁文超老师…

如何计算KST指标,昂首资本一个公式计算

在上一篇文章中&#xff0c;Anzo Capital昂首资本和各位投资者一起了解了KST指标&#xff0c;今天我们继续分享如何计算KST指标。 首先投资者可以在时间范围9、12、18和24分析变化率值。 前三个值(时间帧9、12、18)用EMA 26平滑&#xff0c;最后一个值用EMA 39平滑。 然后&…

从0开始搭建基于VUE的前端项目

准备与版本 安装nodejs(v20.11.1)安装vue脚手架(vue/cli 5.0.8) ,参考&#xff08;https://cli.vuejs.org/zh/&#xff09;vue版本&#xff08;2.7.16&#xff09;&#xff0c;vue2的最后一个版本 初始化项目 创建一个git项目&#xff08;可以去gitee/github上创建&#xff…

数据分析之POWER Piovt透视表分析

将几个数据表之间进行关联 生成数据透视表 超级透视表这里的字段包含子字段 这三个月份在前面的解决办法 1.选中这三个月份&#xff0c;鼠标可移动的时候移动到后面 2.在原数据进行修改 添加列获取月份&#xff0c;借助month的函数双击日期 选择月份这列----按列排序-----选择月…

搜索与图论——Dijkstra算法求最短路

最短路算法 稠密图与稀疏图 n为点数&#xff0c;m为边数。m远小于n的平方为稀疏图&#xff0c;m接近n的平方为稠密图。 稀疏图用邻接表存&#xff0c;稠密图用邻接矩阵存 朴素版dijkstra时间复杂度为O(n^2),对于稠密图可以ac&#xff0c;但遇到稀疏图时会TLE。 dijkstra函数实…

Linux权限管理

文章目录 linux权限管理1.Linux权限的概念2.Linux权限管理2.1 文件访问者的分类&#xff08;人&#xff09;2.2 文件类型和访问权限&#xff08;事物属性&#xff09;2.2.1 文件类型2.2.2 基本权限 2.3文件权限值的表示方法2.3.1 字符表示方法2.3.2 八进制数值表示方法 2.4 文件…

CV领域 交叉注意力(Cross Attention)中QKV的含义理解

交叉注意力公式&#xff1a; 注意力的输入&#xff1a; &#xff08;1&#xff09;KV&#xff1a;图像的全局特征 &#xff08;2&#xff09;Q&#xff1a;告诉attention需要关注哪些重要特征 公式计算过程理解&#xff1a; &#xff08;1&#xff09;&#xff1a;Q和K相乘…

后疫情时代CS保研沉思录暨2023年个人保研经验贴

个人情况 正如古话所说&#xff0c;最适合你的才是最好的。因此这里先贴上个人基本情况&#xff0c;用作参考。 如果你的个人情况与我相近&#xff0c;则有更强的参考作用。如果情况相差较大&#xff0c;也可以姑且引为例子来研究。 学校层次&#xff1a;中流至末流211 专业…

C之易错注意点转义字符,sizeof,scanf,printf

目录 前言 一&#xff1a;转义字符 1.转义字符顾名思义就是转换原来意思的字符 2.常见的转义字符 1.特殊\b 2. 特殊\ddd和\xdd 3.转义字符常错点----计算字符串长度 注意 &#xff1a; 如果出现\890,\921这些的不是属于\ddd类型的&#xff0c;&#xff0c;不是一个字符…