首页 > 编程语言 >LeetCode100之买卖股票的最佳时机含冷冻期(309)--Java

LeetCode100之买卖股票的最佳时机含冷冻期(309)--Java

时间:2024-11-08 23:19:57浏览次数:3  
标签:309 状态 -- 股票 LeetCode100 max prices 冷冻 dp

1.问题描述

   给定一个整数数组prices,其中第  prices[i] 表示第 i 天的股票价格 。​设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

  • 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

        注意

        你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)

        示例1

输入: prices = [1,2,3,0,2]
输出: 3 
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]

        示例2 

输入: prices = [1]
输出: 0

        提示

  • 1 <= prices.length <= 5000
  • 0 <= prices[i] <= 1000

        难度等级

                中等

        题目链接

        买卖股票的最佳时机含冷冻期

2.解题思路

         这道股市市场交易的题目我们得用动态规划的思想来解决,有点困难,因为加入冷冻期之后,股票的状态有点多,不过没关系,我们一步一步来分析。

        在这道题里面,一共有四种状态,第一种是持有股票的状态,第二种是不持有股票的状态,第三种当天卖出股票的状态,第四种是冷冻期的状态。

        首先第一步,我们得有一个dp数组。创建一个dp[prices.length][4]的数组,dp数组的含义是第i天第k种状态的收益。在这道题里我们一共有4种状态,0 表示持有股票的状态、1 表示不持有股票的状态、2 表示当天卖出股票的状态 、3 表示冷冻期的状态。如果一开始不知道有多少种状态,可以向空着,一步一步分析完再来填写。

        //dp数组:第i天股票第k种状态的收益
        int[][] dp = new int[prices.length][4];

        明确了dp数组的含义之后,我们接下来就要确定递推公式。我们先从简单的开始入手。

        如果当天是冷冻期的状态,那么前一天一定是卖出了股票,所以我们就可以得到冷冻期状态的递推公式:dp[i][3] = dp[i-1][2]。

            //今天是冷冻期状态
            dp[i][3] = dp[i-1][2];

        如果当天是卖出股票的状态,那么前一天一定持有股票,卖出股票就能够得到收益,所以我们也可以得到当天卖出股票状态的递推公式:dp[i][2] = dp[i-1][0] + prices[i]。

            //今天卖出状态
            dp[i][2] = dp[i-1][0] + prices[i];

        如果当天是不持有股票的状态,那么可能是前一天我们卖出了股票(dp[i-1][2]),也可能是前一天是冷冻期(dp[i-1][3]),还有可能前一天我们本来就不持有股票(dp[i-1][1]),所以我们也可以得到不持有股票状态的递推公式:dp[i][1] = max(dp[i-1][2],dp[i-1][3],dp[i-1][1])。

            //不持有股票的状态
            dp[i][1] = Math.max(Math.max(dp[i-1][1],dp[i-1][3]),dp[i-1][2]);

        如果当天是持有股票的状态,那么可能是我们前一天就持有股票(dp[i-1][0]),也可能是我们前一天是冷冻期,过了冷冻期今天买股票,买股票是要扣钱的(dp[i-1][3] - prices[i]),还有一种可能是我们前一天不是冷冻期但是也没有持有股票,然后今天买股票(dp[i-1][1] - prices[i])。

            //持有股票状态
            dp[i][0] = Math.max(Math.max(dp[i-1][0],dp[i-1][1] - prices[i]),dp[i-1][3] - prices[i]);

        这样一通分析,我们的递推公式就全部出来了,接着我们就要来初始化一下我们的dp数组。根据dp数组的含义和我们四个状态的递推公式,来初始化。还是从简单的开始来。冷冻期状态,我们没有-1天,所以第0天不可能是冷冻期,初始化为0。卖出股票状态,我们第0天还没开始操作了,所以也初始化为0。不持有股票的状态,我们第0天肯定是持有股票的,这是不然都没办法交易,所以也初始化为0。持有股票的状态,我们第0天肯定要持有股票,才有后续的操作,所以第0天我们要买入股票,初始化为-prices[0]。这样一来,我们的初始化就全部完成了。

        //初始化dp数组
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        dp[0][2] = 0;
        dp[0][3] = 0;

        接着只要遍历数组,递推公式进行推到即可。最大的收益可能在不持有股票,今天卖出股票和冷冻期中的其中一个,我们去最后一天这三个的最大值就可以了。为什么没有状态一持有股票呢?因为卖掉肯定赚钱,买还要倒扣钱。

        return Math.max(Math.max(dp[prices.length-1][3],dp[prices.length-1][1]),dp[prices.length-1][2]);

3.代码展示

class Solution {
    public int maxProfit(int[] prices) {
        //dp数组:第i天股票第k种状态的收益
        int[][] dp = new int[prices.length][4];
        //初始化dp数组
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        dp[0][2] = 0;
        dp[0][3] = 0;
        //遍历
        for(int i = 1;i < prices.length;i++){
            //持有股票状态
            dp[i][0] = Math.max(Math.max(dp[i-1][0],dp[i-1][1] - prices[i]),dp[i-1][3] - prices[i]);
            //不持有股票的状态
            dp[i][1] = Math.max(Math.max(dp[i-1][1],dp[i-1][3]),dp[i-1][2]);
            //今天卖出状态
            dp[i][2] = dp[i-1][0] + prices[i];
            //今天是冷冻期状态
            dp[i][3] = dp[i-1][2];
        }
        return Math.max(Math.max(dp[prices.length-1][3],dp[prices.length-1][1]),dp[prices.length-1][2]);
    }
}

4.总结

        这道题比较难的地方就在于状态比较多,我们需要耐心的分析出各个状态的情况和如何初始化,分析完之后,这道题其实也就解决了大半了。我们一共有四种状态,持有股票、不持有股票、当天卖出和冷冻期,状态较多,我们可以从容易的开始,一步一步逐个击破。我在昨天发的一道MarsCode的题(股票市场交易策略优化)和这道题完全一模一样,只是变量名和描述换了而已,大家也可以去做一下那道题。好了,今天这道题就讲到这里了,祝大家刷题愉快~

标签:309,状态,--,股票,LeetCode100,max,prices,冷冻,dp
From: https://blog.csdn.net/2301_79318558/article/details/143449840

相关文章

  • 20222312 2024-2025-2 《网络与系统攻防技术》实验四报告
    一、恶意代码文件类型标识、脱壳与字符串提取对提供的rada恶意代码样本,进行文件类型识别,脱壳与字符串提取,以获得rada恶意代码的编写作者(1).通过kali中的file命令查看文件格式和可运行平台,即exe文件,Win32平台通过PEID查壳文件发现使用UPX壳二、使用IDAPro静态或动态分析crackm......
  • 数学笑话合集
    Arxiv上一篇数学笑话收集,由数学家TanyaKhovanova撰写(2403.01010)文章内容摘要多年来,我一直在我的网站上收集和发布数学笑话。那里有超过400个笑话。在这篇论文中,它是我在G4G15会议上演讲的扩展版本,我想呈现其中的66个笑话。1数学家与幽默数学家非常逻辑和精确。这里有......
  • 点阵LED电路分析
    以点阵的左上角LED为例,即A1LED为例,进行电路分析9号脚接着LED的阳极,所以9号脚需是高电平,13号脚连着LED的阴极,所以13号脚需是低电平9号脚连接着Q10的集电极,欲使9号脚为高电平,则需要Q10导通Q10的发射极连接着+5V电压,欲使Q10导通,则基极需为低电平,即LEDC0为低电平欲使13号脚低电......
  • 基于微信小程序的婚庆摄影系统设计与实现(源码+论文+部署讲解等)
    博主介绍:✌全网粉丝60W+,csdn特邀作者、Java领域优质创作者、csdn/掘金/哔哩哔哩/知乎/道客/小红书等平台优质作者,计算机毕设实战导师,目前专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌技术栈范围:SpringBoot、Vue、SSM、Jsp、HLMT、Nodejs......
  • Java后端请求想接收多个对象入参的数据方法
    在Java后端开发中,如果我们希望接收多个对象作为HTTP请求的入参,可以使用SpringBoot框架来简化这一过程。SpringBoot提供了强大的RESTfulAPI支持,能够方便地处理各种HTTP请求。1.示例:使用SpringBoot接收包含多个对象的HTTP请求以下是一个详细的示例,展示了如何使用SpringBoot接......
  • 基于微信小程序的考研资料分享系统设计与实现(源码+论文+部署讲解等)
    博主介绍:✌全网粉丝60W+,csdn特邀作者、Java领域优质创作者、csdn/掘金/哔哩哔哩/知乎/道客/小红书等平台优质作者,计算机毕设实战导师,目前专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌技术栈范围:SpringBoot、Vue、SSM、Jsp、HLMT、Nodejs......
  • 链表
    链表部分(链表)707.设计链表(模版,通过了valgrind测试)实现单向链表,即每个节点仅存储本身的值和后继节点。除此之外,我们还需要一个哨兵(sentinel)节点作为头节点,和一个size参数保存有效节点数。如下图所示。初始化时,只需创建头节点head和size即可。实现get(index)时,......
  • 农经权中如何利用地块信息表、家庭成员表、合同面积表生成公示表
    农经权确权过程中要收集很多信息,最重要的信息为每户有多少块地,这户又有多少人来着。在村里公示的时候,不仅要有图纸公示位置,而且要有对应的表格看公示信息。然而存在一个问题,一户的地块数跟家庭成员数量不会有对应关系,用excel表格处理,没法做到将地块表与家庭成员表结合到一块。......
  • 数据结构实验(串的实现)
    实验串的实现一、实验目的1.掌握串的基本概念;2.理解串的几种存储表示及其特点;3.掌握串的常用操作的实现。二、实验环境硬件:计算机一台;软件:VisualStudio。三、实验内容串分别采用顺序存储方式的前提下,完成如下两个任务:1.串比较操作:编写一个比较串s和串t两个串是否相......
  • Linux下含有中文日志输出到终端显示不出来
    问题描述:今天遇到一个中文日志输出到终端显示不出来的问题。用户要升级操作系统,由redhat7.9升级到redhat8.6,x86_64的环境。升级完后,交易服务端程序启动过程中,预期是会在终端输出一些标准输出或标准错误的日志信息,用于提示服务端程序启动过程中的状态,日志信息中包含中文字......