代码随想录刷题day51|股票买卖(含冷冻期)股票买卖(含手续费)

文章目录

  • day51学习内容
  • 一、股票买卖--含冷冻期
    • 1.1、动态规划五部曲
      • 1.1.1、 确定dp数组(dp table)以及下标的含义
      • 1.1.2、确定递推公式
      • 1.1.3、 dp数组如何初始化
      • 1.1.4、确定遍历顺序
      • 1.1.5、输出结果
    • 1.2、代码
  • 二、股票买卖--含手续费
    • 2.1、动态规划五部曲
      • 2.1.1、 确定dp数组(dp table)以及下标的含义
      • 2.1.2、确定递推公式
      • 2.1.3、 dp数组如何初始化
      • 2.1.4、确定遍历顺序
      • 2.1.5、输出结果
    • 2.2、代码
  • 总结
    • 1.感想
    • 2.思维导图


day51学习内容

day51主要内容

  • 股票买卖(含冷冻期)
  • 股票买卖(含手续费)

声明
本文思路和文字,引用自《代码随想录》


一、股票买卖–含冷冻期

309.原题链接

1.1、动态规划五部曲

1.1.1、 确定dp数组(dp table)以及下标的含义

  • 其中dp[i][j]表示在第i天结束时,处于某种特定状态j的最大利润。
  • 为了节省空间,这里采用了循环数组的技巧,即dp[i % 2][j],这意味着它只用一个2x4的数组来保存当前和前一天的状态,而不是用一个长度为len的数组。

状态定义
在给出的代码中,dp[i % 2][j]的四种状态具体定义如下:

  • [i][0]:持有股票(包括当天买入和之前就买入的情况)
  • [i][1]:经过冷冻期后,不持有股票且没有当天买入
  • [i][2]:在当天卖出股票
  • [i][3]:处于冷冻期(即在前一天卖出了股票)

1.1.2、确定递推公式

  1. 持有股票([i][0])的状态转移

    • 可以从前一天就持有股票的状态继续持有。
    • 可以在今天买入股票,这可以发生在前一天是冷冻期后或者是非冷冻期但不持股的状态之后。
  2. 非冷冻期且不持股([i][1])的状态转移

    • 如果前一天也是非冷冻期且不持股,则继续保持这个状态。
    • 如果前一天是冷冻期,那么今天自动转为非冷冻期且不持股。
  3. 卖出股票([i][2])的状态转移

    • 如果今天卖出股票,那么显然是从前一天持有股票的状态转变来的。
  4. 冷冻期([i][3])的状态转移

    • 冷冻期状态只能从前一天卖出股票的状态转变而来。

1.1.3、 dp数组如何初始化

dp数组是一个2x4的二维数组,用于存储在给定天数下,处于不同状态时的最大利润。由于使用了循环数组的技巧,实际上只需要存储当前和前一天的状态,因此第一维的大小为2。第二维的大小为4,对应四种不同的状态。

第0天的初始化

  • dp[0][0] = -prices[0]:这表示在第0天买入股票,所以利润是负的股票价格。这是因为持有股票意味着支付了股票价格的成本。
  • 对于其他的状态,在代码中没有显式初始化,但Java会默认将int数组的元素初始化为0。对于本问题,这意味着:
    • dp[0][1]默认为0,表示在第0天结束时,不持有股票且没有买入股票(在开始之前,我们就处于这个状态)的利润为0。
    • dp[0][2]在第0天是没有意义的,因为你不能在市场还未开始时就卖出股票。所以,虽然它被初始化为0,这个值在逻辑上不会被使用。
    • dp[0][3]表示处于冷冻期,同样在第0天是没有意义的,因为冷冻期是卖出股票后的状态,而在开始时还没有发生任何交易。

1.1.4、确定遍历顺序

从小到大遍历

1.1.5、输出结果

最后一天结束时,可能处于三种状态:非冷冻期且不持股、卖出股票、或是冷冻期。持有股票的状态不是最终的目标状态,因为题目的目的是最大化利润,而持有股票意味着尚未实现利润。因此,最终利润是这三种状态利润的最大值。

1.2、代码

class Solution {public int maxProfit(int[] prices) {int len = prices.length;int dp[][] = new int[2][4];dp[0][0] = -prices[0];for (int i = 1; i < len; i++) {dp[i % 2][0] = Math.max(Math.max(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1] - prices[i]),dp[(i - 1) % 2][3] - prices[i]);dp[i % 2][1] = Math.max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][3]);dp[i % 2][2] = dp[(i - 1) % 2][0] + prices[i];dp[i % 2][3] = dp[(i - 1) % 2][2];}return Math.max(Math.max(dp[(len - 1) % 2][1], dp[(len - 1) % 2][2]), dp[(len - 1) % 2][3]);}
}

二、股票买卖–含手续费

714.原题链接

2.1、动态规划五部曲

2.1.1、 确定dp数组(dp table)以及下标的含义

  • dp:一个二维数组,用于存储动态规划的状态。
    • dp[i][0]表示第i天持有股票时的最大利润。
    • dp[i][1]表示第i天不持有股票时的最大利润。

2.1.2、确定递推公式

对于每一天i(从第1天开始迭代),动态规划的状态转移方程如下:

  • dp[i][0]:第i天持有股票的最大利润可以从以下两种情况中取较大值:
    • dp[i - 1][0]:前一天就持有股票,所以今天没有交易发生。
    • dp[i - 1][1] - prices[i]:前一天不持有股票,今天买入股票,需要支付prices[i]的购买成本。
  • dp[i][1]:第i天不持有股票的最大利润也可以从以下两种情况中取较大值:
    • dp[i - 1][1]:前一天就不持有股票,所以今天没有交易发生。
    • dp[i - 1][0] + prices[i] - fee:前一天持有股票,今天卖出股票,除了获得prices[i]的卖出收益外,还需要支付fee的手续费。

2.1.3、 dp数组如何初始化

  • dp[0][0] = -prices[0]:在第0天(即开始时)买入股票的情况,所以利润是负的股票价格。
  • 第0天不持有股票的利润默认为0(即dp[0][1]),因为在开始时没有股票可以卖出。

2.1.4、确定遍历顺序

从小到大遍历

2.1.5、输出结果

由于最后一天结束时持有股票的状态不一定比不持有股票的状态利润高,所以需要比较dp[len - 1][0]dp[len - 1][1],返回两者中的最大值作为最终的最大利润。

2.2、代码

public int maxProfit(int[] prices, int fee) {int len = prices.length;int[][] dp = new int[len][2];dp[0][0] = -prices[0];for (int i = 1; i < len; i++) {dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i]);dp[i][1] = Math.max(dp[i - 1][0] + prices[i] - fee, dp[i - 1][1]);}return Math.max(dp[len - 1][0], dp[len - 1][1]);
}

总结

1.感想

  • 麻了。股票系列终于结束了

2.思维导图

本文思路引用自代码随想录,感谢代码随想录作者。

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

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

相关文章

批量clone某个github用户的所有项目

要批量克隆某个 GitHub 用户的所有仓库&#xff0c;你可以使用 GitHub API 来列出该用户的所有仓库&#xff0c;并使用命令行工具来进行克隆。以下是一种可能的方法&#xff1a; 获取 GitHub API 访问令牌&#xff1a;首先&#xff0c;你需要在 GitHub 上生成一个访问令牌&…

蓝牙app设计(方案二) E4A (时钟 优缺点)

例程改的! 主界面 虽然上面有搜索功能,但是本人建议先自行配对在使用,这样更好用,把要使用的设备收藏一下更好找哦(这样就是橙色的了,只需要点对应蓝牙左边) 代码修改部分 原版是不停向下滚动显示,这样个人觉得不太好看,所以加了个时钟,到对应时钟周期清空(达到刷…

BGP小实验

光只是知道理论还不行&#xff0c;还是要多动手练练&#xff0c;就练一个bgp实验吧&#xff0c;梳理一下做题思路 实验要求&#xff1a; 大体要求就是&#xff1a;R1的环回可以ping通R2-R5的环回&#xff0c;R5同理 思路&#xff1a; 基础配置&#xff1a; 第一步先把地址环…

二叉树练习day.7

530.二叉搜索树的最小绝对差 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝对值。 示例 1&…

【记录】Prompt模板|作为甲方怎么清晰专业地描述自己的需求(又名“乙方,给你的甲方扔个GPT解放自己吧”)

这篇Prompt摘抄并修改自朋友送给我的书的第49页5.2.3让ChatGPT构建提示&#xff0c;质量挺不错&#xff0c;支持一下她的博客&#xff1a;【好书推荐2】AI提示工程实战&#xff1a;从零开始利用提示工程学习应用大语言模型。 书长这样&#xff1a; 不啰嗦了&#xff0c;正文如…

多张图如何制作一图一码?图片批量转二维码的制作方法

二维码现在经常被用来作为图片的载体&#xff0c;将图片生成二维码之后通过扫描二维码的方式来查看图片信息&#xff0c;那么如果遇到需要将几十张图片分别单独制作二维码的需求时&#xff0c;有什么方法能够一次性批量建码呢&#xff0c;相信有很多的小伙伴对这个问题的解决方…

关于conda安装pytorch gpu总是会自动变成cpu版本

这篇文章讲了三种方法&#xff0c;由于我使用的服务器无法连接外网&#xff0c;所以这些方法我没成功安装的pytorch不是GPU版本而是CPU版本_pytorch安装包里只是cpu-CSDN博客 然后我瞎试发现使用 conda install dataclasses 居然能够连带着把gpu版本的pytorch下载下来&…

arm64位系统中编译ffmpeg

大致过程仍然和x86平台一致&#xff1a; ./configure xxxxmakemake install 所需要变化的是需要在 ./configure xxxx 后面多加几个编译选项 cd ffmpeg ./configure (x64下的依赖配置&#xff1a;......)--prefixbin --archaarch64 --target-oslinux --enable-cross-compile …

水仙花数python

水仙花数&#xff08;Narcissistic number&#xff09;是指一个n位正整数&#xff0c;其各位数字的n次幂之和等于该数本身。例如&#xff0c;153是一个3位的水仙花数&#xff0c;因为&#xff1a;1^3 5^3 3^3 153。在Python中&#xff0c;你可以编写一个简单的脚本来找到所有…

Linux:systemd和systemctl基本使用示例

目录 systemd管理Flask应用示例systemctl常用操作 文档 https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.htmlSystemd 入门教程&#xff1a;命令篇Systemd 入门教程&#xff1a;实战篇 systemd管理Flask应用示例 创建虚拟环境&#xff0c;做好环境隔…

探秘冒泡排序:原理、实现与优化策略

冒泡排序&#xff0c;以其直观易懂的名称和简单朴素的操作&#xff0c;成为了许多初学者接触排序算法的首选。本文将详细解析冒泡排序的原理、实现步骤&#xff0c;并探讨其优化策略及应用场景&#xff0c;帮助读者全面理解这一经典排序算法的魅力所在。 一、冒泡排序原理 冒…

设计模式学习笔记 - 设计模式与范式 -行为型:13.访问者模式(下):为什么支持双分派的语言不需要访问者模式

概述 上篇文章&#xff0c;我们学习了访问者模式的原理和实现&#xff0c;并还原了访问者模式诞生的过程。总体来说&#xff0c;这个模式的代码实现比较难&#xff0c;所以应用场景不多。从应用开发的角度来说&#xff0c;它的确不是我们学习的重点。 本章&#xff0c;我们把…

高并发高性能接口中,异步打印并采集业务日志的实现方案

一、背景 高并发接口中&#xff0c;为了提高接口的高性能&#xff0c;在需要保存审计及操作记录的时候&#xff0c;往往有以下常见方案&#xff1a; 保存到redis数据库异步保存到mysql/mongodb/es等数据库logger打印业务日志&#xff0c;采集与展示则交由elk模块 对于第一种…

OpenLayers6实战,OpenLayers实现鼠标拖拽方式绘制平行四边形

专栏目录: OpenLayers实战进阶专栏目录 前言 本章介绍如何使用OpenLayers在地图上使用实现鼠标拖拽方式绘制平行四边形。 二、依赖和使用 "ol": "^6.15.1"使用npm安装依赖npm install ol@6.15.1使用Yarn安装依赖yarn add olvue中如何使用: vue项目…

初学SSRF总结

什么是SSRF SSRF是由攻击者构造通过服务端发起请求的安全漏洞。通常情况下&#xff0c;SSRF的攻击对象是外部无法访问的内网&#xff08;因为是由服务端发起的请求所以攻击能够访问到内部系统&#xff09; 由于服务端提供了从其它服务器获取数据的功能&#xff0c;但是有没有…

SPLD论文笔记

SLPD论文笔记 题目&#xff1a;SLPD: Slide-Level Prototypical Distillation for WSIs 摘要 提高特征表示能力是许多全玻片病理图像 &#xff08;WSI&#xff09; 任务的基础。最近的工作在病理特异性自我监督学习&#xff08;SSL&#xff09;方面取得了巨大成功。然而&…

C++初阶:反向迭代器

reverse_iterator的封装实现 Reverse_Iterator.h namespace xx {// 所有容器的反向迭代器// 迭代器适配器template<class Iterator, class Ref, class Ptr>struct Reverse_iterator{Iterator _it;typedef Reverse_iterator<Iterator, Ref, Ptr> Self;Reverse_iter…

Vue中如何使用Tailwind CSS样式?多次引用不成功?具体步骤怎么做?

一、安装Tailwind CSS和依赖 在你的Vue项目中安装Tailwind CSS及其依赖。你可以使用npm或yarn来安装。 npm install tailwindcsslatest postcsslatest autoprefixerlatest # 或者yarn add tailwindcsslatest postcsslatest autoprefixerlatest 二、初始化Tailwind CSS np…

Linux系统中MySQL数据库大小写敏感

问题描述 最近把网站向一台新的CentOS服务器中做迁移&#xff0c;把MySQL数据库和前后端站点全都部署完成后&#xff0c;网站启动之后一直在报表名不存在的错误。 开始略微疑惑&#xff0c;以为是做数据库备份的时候漏了表&#xff0c;检查后发现并不是这么回事。 略一思索&a…

Linux系统中安装 RPM 包

rpm -ivh 是在Linux系统中用来安装 RPM 包的命令。RPM&#xff08;Red Hat Package Manager&#xff09;是一种用于在基于Red Hat的Linux系统&#xff08;如Fedora、CentOS、Red Hat Enterprise Linux等&#xff09;上管理软件包的工具。 rpm -ivh 命令的作用&#xff1a; 安…