DAY52:动态规划(打家劫舍系列)

2024-02-17 23:20

本文主要是介绍DAY52:动态规划(打家劫舍系列),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Leetcode: 198 打家劫舍

基本思路

1、dp下标

dp[i]表示下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]。

2、递推公式

如果偷第i房间,那么dp[i] = dp[i - 2] + nums[i]。

如果不偷第i房间,那么dp[i] = dp[i - 1]。

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

3、初始化

dp[0]为num[0],dp[1]为max(num[0],num[1])

时间复杂度: O(n)

空间复杂度: O(n)

class Solution {
public:int rob(vector<int>& nums) {if (nums.size() == 0) return 0;//注意先对特殊情况进行剪枝if (nums.size() == 1) return nums[0];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 - 2] + nums[i], dp[i - 1]);//递推公式}return dp[nums.size() - 1];}
};

Leetcode: 213 打家劫舍II

与上题不同点在于,这个地方所有的房屋都围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。唯一差别在于环的出现。

可以分为两种情况

1、考虑首元素,不考虑尾元素

2、考虑尾元素,不考虑首元素

因此只需要这两种情况都考虑,选一个最大的就可以。

可以写成统一的函数。也可以写两遍。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution {
public:int rob(vector<int>& nums) {if (nums.size() == 0) return 0;//注意先对特殊情况进行剪枝if (nums.size() == 1) return nums[0];int result1 = findresult(nums, 0, nums.size() - 2);//考虑首int result2 = findresult(nums, 1, nums.size() - 1);//考虑尾return max(result1, result2);}int findresult(vector<int>& nums , int start, int end){if(start == end) return nums[start];vector<int> dp(nums.size(),0);dp[start] = nums[start];//初始化dp[start + 1] = max(nums[start], nums[start + 1]);for(int i = start + 2; i <= end; i++){dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);}return dp[end];//返回结果}
};

Leetcode: 337 打家劫舍III

与上两题不同,是因为这道题房屋是按照二叉树来进行排列的,因此涉及到树的遍历问题。

树形dp

因为动态规划函数需要通过数据进行计算,所以需要后序遍历,按照左右中的顺序来。

代码随想录

基本思路

1、确定递归函数的参数和返回值

这里我们要求一个节点 偷与不偷的两个状态所得到的金钱,那么返回值就是一个长度为2的数组。

所以dp数组[0]存储不偷该节点的最大金钱,[1]存储偷该节点的最大金钱。

2、确定终止条件

在遍历的过程中,如果遇到空节点的话,很明显,无论偷还是不偷都是0,所以就返回{0,0}

3、遍历顺序

后序遍历

4、递归逻辑

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

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

时间复杂度:O(n)

空间复杂度:O(log n)

class Solution {
public:int rob(TreeNode* root) {vector<int> result = robTree(root);return max(result[0], result[1]);}vector<int> robTree(TreeNode* cur) {if(cur == NULL) return vector<int>{0,0};vector<int> left = robTree(cur->left);//左vector<int> right = robTree(cur->right);//右//dp状态转移公式,中// 偷cur,那么就不能偷左右节点。int val1 = cur->val + left[0] + right[0];// 不偷cur,那么可以偷也可以不偷左右节点,则取较大的情况int val2 = max(left[0], left[1]) + max(right[0], right[1]);return {val2, val1};}
};

这篇关于DAY52:动态规划(打家劫舍系列)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/719298

相关文章

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

如何用Python绘制简易动态圣诞树

《如何用Python绘制简易动态圣诞树》这篇文章主要给大家介绍了关于如何用Python绘制简易动态圣诞树,文中讲解了如何通过编写代码来实现特定的效果,包括代码的编写技巧和效果的展示,需要的朋友可以参考... 目录代码:效果:总结 代码:import randomimport timefrom math

Java中JSON字符串反序列化(动态泛型)

《Java中JSON字符串反序列化(动态泛型)》文章讨论了在定时任务中使用反射调用目标对象时处理动态参数的问题,通过将方法参数存储为JSON字符串并进行反序列化,可以实现动态调用,然而,这种方式容易导... 需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。方案一:将方法参数存成jsON字

.NET利用C#字节流动态操作Excel文件

《.NET利用C#字节流动态操作Excel文件》在.NET开发中,通过字节流动态操作Excel文件提供了一种高效且灵活的方式处理数据,本文将演示如何在.NET平台使用C#通过字节流创建,读取,编辑及保... 目录用C#创建并保存Excel工作簿为字节流用C#通过字节流直接读取Excel文件数据用C#通过字节

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言