️思维导图整理大厂面试高频数组21: 股票问题+冷冻期的两种dp数组定义方式, 力扣309️-程序员宅基地

技术标签: 面试  力扣  买卖股票的最佳时机  思维导图整理大厂面试高频力扣题  1024程序员节  动态规划  

此专栏文章是对力扣上算法题目各种方法总结和归纳, 整理出最重要的思路和知识重点并以思维导图形式呈现, 当然也会加上我对导图的详解.

目的是为了更方便快捷的记忆和回忆算法重点(不用每次都重复看题解), 毕竟算法不是做了一遍就能完全记住的. 所以本文适合已经知道解题思路和方法, 想进一步加强理解和记忆的朋友, 并不适合第一次接触此题的朋友(可以根据题号先去力扣看看官方题解, 然后再看本文内容).

关于本专栏所有题目的目录链接, 刷算法题目的顺序/注意点/技巧, 以及思维导图源文件问题请点击此链接.

想进大厂, 刷算法是必不可少的, 欢迎和博主一起打卡刷力扣算法, 博主同步更新了算法视频讲解 和 其他文章/导图讲解, 更易于理解, 欢迎来看!

关注博主获得题解更新的最新消息!!!

题目链接: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/solution/si-wei-dao-tu-zheng-li-liang-chong-dpshu-4vu3/

0.导图整理

1.两个状态的动态规划

1.1 两个状态的思想

本题就是在 股票II买卖多次 的基础上增加了冷冻期的条件, dp数组定义过程基本相似, 大家可以先看完上面的题解, 再来看本题题解.

大家在看其他题解的时候, 肯定大部分都是三个状态的动态规划解法, 这种解法也确实符合一般的思路, 毕竟前面几题我们大多都定义的两个状态: 持有have[i]和不持有no[i]股票, 现在多了个冷冻期的附加条件, 那自然想到再多加一个状态单独表示冷冻期的情况. 但总感觉这样的三个状态和前面几题就不统一了, 那么能不能还用两个状态解决此题呢?

我们首先观察下冷冻期的概念, 它是在股票卖出之后才会出现的情况, 也就是说处于冷冻期时一定是不持有股票的, 所以可以将它合并到状态no[i]中, 这样就将三个状态成功转化为两个状态了.

1.2 递推公式的变化

状态定义完了, 就是递推公式的推导了, 根据之前的经验, 递推公式由四种情况组合而成, 而这四种情况中和冷冻期有关的就只有 第i天买入股票 的情况了, 其他的三种状态都和冷冻期关系不大, 并未受太大影响, 递推公式也没什么变化.

下面我们就来着重分析这种情况, 当第i天买入股票时, 那第i-1天必定是不持有股票且不能是冷冻期, 而只用no[i-1]这个状态并不能区别出是否为冷冻期, 所以这里我们采用no[i-2]这个状态.

现在我们来说明这个状态的合理性: no[i-2]由两种情况组成:

  • 如果no[i-2]是在第i-2天卖出股票, 那第i-1天就是冷冻期, 那第i天就解冻了.
  • 如果no[i-2]是延续了前一天i-3天不持有股票的状态, 那么在第i-1天就不会有股票被卖出, 那么第i天也不会是冷冻期.

综合上述两种情况, 无论no[i-2]是由哪个情况转移而来, 第i天都不是冷冻期.

1.3 no[i-2]是否为最大利润

上述说明了使用了no[i-2]的合理性, 那么就剩最后一个问题了, 我们跳过了no[i-1]这个状态, 那么no[i-2]是否就是当前的最大利润呢?

这里还是用上述no[i-2]的两种情况来说明:

  • 如果no[i-2]是在第i-2天卖出股票, 那第i-1天就是冷冻期, 利润不会发生变化.
  • 如果no[i-2]是延续了前一天i-3天不持有股票的状态, 那么在i-1天可能延续i-2天不持有股票的状态, 利润仍然不变, 也可能在i-1天买入股票, 首先利润就变小了, 其次状态也变为have[i-1], 不是我们需要的no状态.

综合两种情况来看, no[i-2]就是当前的最大利润, 这点理解之后, 递推公式就没什么难度了.

1.4 初始化的不同

之前都是初始化了have[0]和no[0]两个状态就可以了, 本题由于使用到了no[i-2]这个状态, 在i=1时是不合法的, 所以本题还要初始化have[1]和no[1]两个状态, 根据递推公式就可以了, 也没什么难度, 就是麻烦了一点.

1.5 空间优化的难点

本题在空间优化上是有点难度的, 因为我们需要用到no[i-2]的状态, 所以必须用变量同时存储no[i-2]和no[i-1]的状态, 变量记录的位置要确定好, 具体实现可以看最后的代码.

2.三个状态的动态规划

上文提到了最常规的思想就是在两个状态的基础上再新增一个状态用来表示冷冻期, 当然no[i]的含义也发生了一点的变化

  • have[i] 表示第i天持有股票所得最多现金
  • no[i] 表示第i天不持有股票且不处于冷冻期所得最多现金
  • cold[i] 表示第i天不持有股票且处于冷冻期所得最多现金

定义了这三个状态之后, 根据之前的经验, 状态转移方程也不难写出, 如下:

这里的have[i]没有变化, cold[i]也很容易写出, 唯一变化较大的就是no[i]了, 可能有人会感觉当天卖出股票也是满足的, 因为到第二天才会是冷冻期.

官方题解的解释是f[i]表示第 i 天结束之后的「累计最大收益」, 这种定义方式确实解决了这个问题, 但理解起来有点麻烦, 感觉绕了一下, 而且这种定义方式和之前的股票问题就有了差距, 不方便将它们整合起来, 所以我的理解是 只要卖出了股票就处于冷冻期, 不一定非要等到第二天, 这样来理解, 问题就容易想清楚了.

源码

Python:

## 两个状态
## 未进行空间优化
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        if n <= 1 :
            return 0
        
        have = [0] * n
        no = [0] * n
        have[0] = - prices[0]
        no[0] = 0     
        have[1] = max(have[0], -prices[1])
        no[1] = max(no[0], have[0] + prices[1])
        for i in range(2, n) :
            no[i] = max(no[i - 1], have[i - 1] + prices[i])
            have[i] = max(have[i - 1], no[i - 2] - prices[i])
        
        return no[n - 1]

## 空间优化
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        if n <= 1 :
            return 0
        
        have = - prices[0] # 对have[0]初始化
        no = 0     
        temp = no # 当i=2时, 记录下第一个no[i-2]
        have = max(have, -prices[1]) # 对have[1]初始化
        no = max(no, have + prices[1])
        for i in range(2, n) :
            no_i2 = temp # 记录下no[i-2]
            temp = no    # 记录下no[i-1]
            no = max(no, have + prices[i])
            have = max(have, no_i2 - prices[i])
        return no

## 三个状态
## 未进行空间优化
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        length = len(prices)
        if len == 0:
            return 0
        have = [0] * length  # 表示第i天持有股票所得最多现金
        no = [0] * length    # 表示第i天不持有股票且不在冷冻期所得最多现金
        cold = [0] * length  # 表示第i天不持有股票且在冷冻期所得最多现金
        have[0] = -prices[0] # 此时的持有股票就一定是买入股票了
        no[0] = 0            # 不持有股票那么现金就是0
        cold[0] = 0
        for i in range(1, length):
            have[i] = max(have[i-1], no[i-1] - prices[i]); 
            no[i] = max(no[i-1], cold[i-1]);
            cold[i] = have[i-1] + prices[i];
        return max(cold[-1], no[-1])

## 空间优化
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        length = len(prices)
        if len == 0:
            return 0

        have = -prices[0] # 此时的持有股票就一定是买入股票了
        no = 0            # 不持有股票那么现金就是0
        cold = 0
        for i in range(1, length):
            have = max(have, no - prices[i]); 
            no = max(no, cold);
            cold = have + prices[i];
        return max(cold, no)

java:

// 两个状态
// 未进行空间优化
class Solution {
    
    public int maxProfit(int[] prices) {
    
        int n = prices.length;
        if (n <= 1) {
    
            return 0;
        }
        int[] have = new int[n];
        int[] no = new int[n];
        have[0] = - prices[0];
        no[0] = 0;     
        have[1] = Math.max(have[0], -prices[1]);
        no[1] = Math.max(no[0], have[0] + prices[1]);
        for (int i = 2; i < n; i++) {
    
            no[i] = Math.max(no[i - 1], have[i - 1] + prices[i]);
            have[i] = Math.max(have[i - 1], no[i - 2] - prices[i]);
        }
        return no[n - 1];
    }
}

// 三个状态
// 未进行空间优化
public class Solution {
    
    public int maxProfit(int[] prices) {
    
        int len = prices.length;
        if (len < 2) {
    
            return 0;
        }
        int[] have = new int[len];  // 表示第i天持有股票所得最多现金
        int[] no = new int[len];    // 表示第i天不持有股票且不在冷冻期所得最多现金
        int[] cold = new int[len];  // 表示第i天不持有股票且在冷冻期所得最多现金
        have[0] = -prices[0]; // 此时的持有股票就一定是买入股票了
        no[0] = 0;            // 不持有股票那么现金就是0
        cold[0] = 0;


        for (int i = 1; i < len; i++) {
    
            have[i] = Math.max(have[i-1], no[i-1] - prices[i]); 
            no[i] = Math.max(no[i-1], cold[i-1]);
            cold[i] = have[i-1] + prices[i];
        }
        return Math.max(cold[len - 1], no[len - 1]);
    }
}

我的更多精彩文章链接, 欢迎查看

各种电脑/软件/生活/音乐/动漫/电影技巧汇总(你肯定能够找到你需要的使用技巧)

力扣算法刷题 根据思维导图整理笔记快速记忆算法重点内容(欢迎和博主一起打卡刷题哦)

计算机专业知识 思维导图整理

最值得收藏的 Python 全部知识点思维导图整理, 附带常用代码/方法/库/数据结构/常见错误/经典思想(持续更新中)

最值得收藏的 C++ 全部知识点思维导图整理(清华大学郑莉版), 东南大学软件工程初试906科目

最值得收藏的 计算机网络 全部知识点思维导图整理(王道考研), 附带经典5层结构中英对照和框架简介

最值得收藏的 算法分析与设计 全部知识点思维导图整理(北大慕课课程)

最值得收藏的 数据结构 全部知识点思维导图整理(王道考研), 附带经典题型整理

最值得收藏的 人工智能导论 全部知识点思维导图整理(王万良慕课课程)

最值得收藏的 数值分析 全部知识点思维导图整理(东北大学慕课课程)

最值得收藏的 数字图像处理 全部知识点思维导图整理(武汉大学慕课课程)

红黑树 一张导图解决红黑树全部插入和删除问题 包含详细操作原理 情况对比

各种常见排序算法的时间/空间复杂度 是否稳定 算法选取的情况 改进 思维导图整理

人工智能课件 算法分析课件 Python课件 数值分析课件 机器学习课件 图像处理课件

考研相关科目 知识点 思维导图整理

考研经验–东南大学软件学院软件工程(这些基础课和专业课的各种坑和复习技巧你应该知道)

东南大学 软件工程 906 数据结构 C++ 历年真题 思维导图整理

东南大学 软件工程 复试3门科目历年真题 思维导图整理

最值得收藏的 考研高等数学 全部知识点思维导图整理(张宇, 汤家凤), 附做题技巧/易错点/知识点整理

最值得收藏的 考研线性代数 全部知识点思维导图整理(张宇, 汤家凤), 附带惯用思维/做题技巧/易错点整理

高等数学 中值定理 一张思维导图解决中值定理所有题型

考研思修 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理

考研近代史 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理

考研马原 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理

考研数学课程笔记 考研英语课程笔记 考研英语单词词根词缀记忆 考研政治课程笔记

Python相关技术 知识点 思维导图整理

Numpy常见用法全部OneNote笔记 全部笔记思维导图整理

Pandas常见用法全部OneNote笔记 全部笔记思维导图整理

Matplotlib常见用法全部OneNote笔记 全部笔记思维导图整理

PyTorch常见用法全部OneNote笔记 全部笔记思维导图整理

Scikit-Learn常见用法全部OneNote笔记 全部笔记思维导图整理

Java相关技术/ssm框架全部笔记

Spring springmvc Mybatis jsp

科技相关 小米手机

小米 红米 历代手机型号大全 发布时间 发布价格

常见手机品牌的各种系列划分及其特点

历代CPU和GPU的性能情况和常见后缀的含义 思维导图整理

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43959833/article/details/120933461

智能推荐

分布式光纤传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_预计2026年中国分布式传感器市场规模有多大-程序员宅基地

文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大

07_08 常用组合逻辑电路结构——为IC设计的延时估计铺垫_基4布斯算法代码-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码

OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版

关于美国计算机奥赛USACO,你想知道的都在这_usaco可以多次提交吗-程序员宅基地

文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗

MySQL存储过程和自定义函数_mysql自定义函数和存储过程-程序员宅基地

文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程

半导体基础知识与PN结_本征半导体电流为0-程序员宅基地

文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0

随便推点

【Unity3d Shader】水面和岩浆效果_unity 岩浆shader-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader

广义线性模型——Logistic回归模型(1)_广义线性回归模型-程序员宅基地

文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型

HTML+CSS大作业 环境网页设计与实现(垃圾分类) web前端开发技术 web课程设计 网页规划与设计_垃圾分类网页设计目标怎么写-程序员宅基地

文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁_.net dll 全局目录-程序员宅基地

文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录

BRIEF特征点描述算法_breif description calculation 特征点-程序员宅基地

文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点

房屋租赁管理系统的设计和实现,SpringBoot计算机毕业设计论文_基于spring boot的房屋租赁系统论文-程序员宅基地

文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文

推荐文章

热门文章

相关标签