代码随想录算法训练营Day48|188.买卖股票的最佳时机IV、309.最佳买卖股票时间含冷冻期、714.买卖股票的最佳时机含手续费

买卖股票的最佳时机IV

. - 力扣(LeetCode)

至多可以购买k次,相比买卖股票的最佳时机III至多购买2次,区别在于次数不确定。

每买卖一次,dp数组的第二维度加2,dp数组的第二维度为2k+1(0-2k)

dp数组 vector<vector<int>>dp(prices.size(),vector<int>(2k+1,0))

表示第i天买入和卖出k次的最大金额

使用for循环遍历天和次数

for(int i = 1; i < prices.size();i++){for(int j = 1; j < 2k+1; j+= 2){}}

代码随想录 (programmercarl.com)

达到dp[i][1]状态,有两个具体操作:

  • 操作一:第i天买入股票了,那么dp[i][1] = dp[i - 1][0] - prices[i]
  • 操作二:第i天没有操作,而是沿用前一天买入的状态,即:dp[i][1] = dp[i - 1][1]

选最大的,所以 dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);

同理dp[i][2]也有两个操作:

  • 操作一:第i天卖出股票了,那么dp[i][2] = dp[i - 1][1] + prices[i]
  • 操作二:第i天没有操作,沿用前一天卖出股票的状态,即:dp[i][2] = dp[i - 1][2]

所以dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2])

初始化情况,当不购买时,全初始化为0,购买的情况都初始化为-prices[0],也用循环实现。

for (int j = 1; j < 2 * k; j += 2) {dp[0][j] = -prices[0];
}

最终代码

class Solution {
public:int maxProfit(int k, vector<int>& prices) {// 如果没有价格数据,则无法进行交易,返回 0if (prices.size() == 0) return 0;// 创建一个二维向量 dp,用于动态规划// dp[i][j] 表示第 i 天结束时,进行了 j 次交易(或部分交易)的最大利润// j 为偶数时表示没有持有股票,j 为奇数时表示持有股票vector<vector<int>> dp(prices.size(), vector<int>(2 * k + 1, 0));// 初始化第 0 天的情况// 第 0 天持有股票的情况,利润为 -prices[0]for (int j = 1; j < 2 * k; j += 2) {dp[0][j] = -prices[0];}// 动态规划计算从第 1 天到第 n-1 天的最大利润for (int i = 1; i < prices.size(); i++) {for (int j = 0; j < 2 * k - 1; j += 2) {// 第 i 天持有股票的最大利润是前一天持有股票的利润和前一天没有股票今天买入的利润的最大值dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);// 第 i 天没有股票的最大利润是前一天没有股票的利润和前一天持有股票今天卖出的利润的最大值dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);}}// 返回最后一天进行了 k 次交易的最大利润return dp[prices.size() - 1][2 * k];}
};

算法的时间复杂度为O((k)*n),空间复杂度为O((k)*n)。

最佳买卖股票时间含冷冻期

. - 力扣(LeetCode)

考虑含冷冻期的问题,需要前两天来保证今天购入并持有股票的状态。

首先,仍然是两个表示今天的股票状态,无持有或持有。分别用0和1表示。

dp[i][0]表示今天结束手头无股票持有所能得到的最大金额。

dp[i][1]表示今天结束手头持有股票所能得到的最大金额。

dp[i][0]为两种情况的较大值,昨日持有,但今日卖出;昨日也为持有,今日也未购买

dp[i][0] = max(dp[i-1][0],dp[i-1][1] + prices[i]);

dp[i][1]为两种情况的较大值,考虑到冷冻期的存在,前天未持有,今天购入;昨天持有,今天也持有。 dp[i][1] = max(dp[i-2][0] - prices[i],dp[i-1][1]);

由此,我们需要对第1、2天进行初始化,dp[0][0] = 0,dp[0][1] = -prices[0],dp[1][0] = max(dp[0][0],dp[0][1] + prices[1]),dp[1][1] = max(dp[0][0] - prices[1],dp[0][1]);

从前向后遍历,最后返回dp[nums.size()-1][0],最后一天的卖出获得的最大金额。

class Solution {
public:int maxProfit(vector<int>& prices) {// 创建一个二维向量 dp,用于动态规划// dp[i][0] 表示第 i 天结束时没有股票的最大利润,dp[i][1] 表示第 i 天结束时持有股票的最大利润vector<vector<int>> dp(prices.size(), vector<int>(2, 0));// 如果只有一天,无法进行交易,返回 0if (prices.size() == 1) {return 0;}// 初始化第 0 天的情况// 第 0 天没有股票,利润为 0dp[0][0] = 0;// 第 0 天买入股票,利润为 -prices[0]dp[0][1] = -prices[0];// 初始化第 1 天的情况// 第 1 天没有股票,利润为 max(第 0 天没有股票的利润, 第 0 天买入第 1 天卖出的利润)dp[1][0] = max(dp[0][0], dp[0][1] + prices[1]);// 第 1 天买入股票,利润为 max(第 0 天没有股票买入股票的利润, 第 0 天买入股票的利润)dp[1][1] = max(dp[0][0] - prices[1], dp[0][1]);// 动态规划计算从第 2 天到第 n-1 天的最大利润for (int i = 2; i < prices.size(); i++) {// 第 i 天没有股票的最大利润是前一天没有股票的利润和前一天有股票今天卖出的利润的最大值dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]);// 第 i 天有股票的最大利润是前一天没有股票今天买入的利润和前一天有股票的利润的最大值dp[i][1] = max(dp[i-2][0] - prices[i], dp[i-1][1]); // 注意这里只能从前两天没有股票的状态转移过来}// 返回最后一天没有股票最大利润return dp[prices.size()-1][0];}
};

算法的时间复杂度为O(n),空间复杂度为O(n)。

买卖股票的最佳时机含手续费

. - 力扣(LeetCode)

题目相比之前的买卖股票的最佳时机II加入了手续费。

只改变了dp数组的推导和初始赋值。

完成一次买入卖出交易需要一次手续费,我们假定在买入时即完成手续费的交易,则dp[i][0]和dp[i][1]的推导如下

dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]);
dp[i][1] = max(dp[i-1][0] - prices[i] - fee, dp[i-1][1]);

初始赋值dp[0][0] = 0;dp[0][1]=-prices[i]-fee;

其他相比买卖股票的最佳时机II没有变化。

class Solution {
public:int maxProfit(vector<int>& prices, int fee) {// dp[i][0] 表示第 i 天结束时没有股票的最大利润,dp[i][1] 表示第 i 天结束时持有股票的最大利润vector<std::vector<int>> dp(prices.size(), std::vector<int>(2, 0));// 初始化第 0 天的情况// 第 0 天没有股票,利润为 0dp[0][0] = 0;// 第 0 天买入股票,利润为 -prices[0] - fee(因为需要支付交易费用)dp[0][1] = -prices[0] - fee;// 动态规划计算从第 1 天到第 n-1 天的最大利润for(int i = 1; i < prices.size(); i++) {// 第 i 天没有股票的最大利润是前一天没有股票的利润和前一天有股票今天卖出的利润的最大值dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]);// 第 i 天有股票的最大利润是前一天没有股票今天买入的利润和前一天有股票的利润的最大值// 买入时需要支付交易费用dp[i][1] = max(dp[i-1][0] - prices[i] - fee, dp[i-1][1]);}// 返回最后一天没有股票的最大利润return dp[prices.size()-1][0];}
};

算法的时间复杂度和空间复杂度为O(n)。

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

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

相关文章

TDengine 3.2.3.0 集成英特尔 AVX512!快来看看为你增添了哪些助力

在当今的 IoT 和智能制造领域&#xff0c;海量时序数据持续产生&#xff0c;对于这些数据的实时存储、高效查询和分析已经成为时序数据库&#xff08;Time Series Database&#xff0c;TSDB&#xff09;的核心竞争力。作为一款高性能的时序数据库&#xff0c;TDengine 不仅采用…

Pandas数据分析:掌握agg()方法的高级应用“

今天一个知识点&#xff1a; agg() 方法的 func 参数可以传入单个函数或函数列表。 agg() 方法在Pandas库中用于对DataFrame或Series的列进行聚合操作。func 参数可以传入单个&#xff08;值得注意的是&#xff0c;这里数据是一个单个而不是多个的内容&#xff0c;自己在这个…

【全开源】沃德会务会议管理系统(FastAdmin+ThinkPHP+Uniapp)

沃德会务会议管理系统一款基于FastAdminThinkPHPUniapp开发的会议管理系统&#xff0c;对会议流程、开支、数量、标准、供应商提供一种标准化的管理方法。以达到量化成本节约&#xff0c;风险缓解和服务质量提升的目的。适用于大型论坛、峰会、学术会议、政府大会、合作伙伴大会…

docker 安装达梦8

背景 X86-64架构使用Docker安装dm8_20240422_x86_rh6_64_rq_std_8.1.3.100_pack2.tar 1.下载Docker安装包 达梦官网下载dm8_20240422_x86_rh6_64_rq_std_8.1.3.100_pack2.tar安装包 快速下载通道&#xff1a; 达梦镜像包 2.将安装包上传至服务器&#xff0c;并加载镜像 拷…

结合人工智能的在线教育系统:开发与实践

人工智能&#xff08;AI&#xff09;正在革新各行各业&#xff0c;教育领域也不例外。结合AI技术的在线教育系统能够提供个性化的学习体验、智能化的教学辅助和高效的数据分析&#xff0c;从而大大提升教育质量和学习效果。本文将探讨结合AI技术的在线教育系统的开发与实践&…

如何调整C#中数组的大小

前言 数组存储多个相同类型的一种非常常用的数据结构。它长度是固定&#xff0c;也就是数组一旦创建大小就固定了。C# 数组不支持动态长度。那在C#中是否有方法可以调整数组大小呢&#xff1f;本文将通过示例介绍一种调整一维数组大小的方法。 方法 数组实例是从 System.Arr…

Type.GetTypeFromProgID 调用com组件

Type.GetTypeFromProgID 方法用于通过程序标识符&#xff08;ProgID&#xff09;获取 COM 类型。ProgID 是一个字符串标识符&#xff0c;用于标识 COM 组件。它通常在注册表中配置&#xff0c;并指向一个具体的 COM 类的 CLSID&#xff08;类标识符&#xff09;。 什么是 Prog…

【数据结构与算法】顺序查找、折半查找、分块查找

文章目录 顺序查找实现对有序表的顺序查找 二分查找&#xff08;折半查找&#xff09;实现二分查找判定树 分块查找&#xff08;索引顺序查找&#xff09;最理想的分块情况 顺序查找 顺序查找&#xff0c;又叫线性查找。适用于线性表。它的核心思路是从线性表的一端开始&#…

Unity的ScrollView滚动视图复用

发现问题 在游戏开发中有一个常见的需求&#xff0c;就是需要在屏幕显示多个&#xff08;多达上百&#xff09;显示item&#xff0c;然后用户用手指滚动视图可以选择需要查看的item。 现在的情况是在100个data的时候&#xff0c;Unity引擎是直接创建出对应的100个显示item。 …

13个行业数据分析指标体系如何建设100问

提供针对13个行业的数据分析指标体系的全面指南&#xff0c;涵盖各行业的关键指标和分析维度&#xff0c;帮助读者深入了解和构建有效的指标体系。以下是文章的主要内容&#xff1a; 电商行业数据指标体系&#xff1a;包括客户价值、商品、网站流量、整体运营、市场营销活动、市…

若依-前后端分离项目学习

第一天&#xff08;6.24&#xff09; 具体参考视频 b站 楠哥教你学Java 【【开源项目学习】若依前后端分离版&#xff0c;通俗易懂&#xff0c;快速上手】 https://www.bilibili.com/video/BV1HT4y1d7oA/?share_sourcecopy_web&vd_sourcecd9334b72b49da3614a4257…

C++如何实现继承和多态

继承 继承是指一个类&#xff08;子类&#xff09;从另一个类&#xff08;父类&#xff09;继承属性和方法。C支持单继承和多继承。 #include <iostream>// 基类&#xff08;父类&#xff09; class Animal { public:// 基类中的方法void eat() {std::cout << &q…

Elasticsearch Scroll 报错entity content is too long

2024-06-24 15:22:01:568 ERROR [task-31] (ScrollFetcherProduceAction.java:129) 访问ES出错org.apache.http.ContentTooLongException: entity content is too long [112750110] for the configured buffer limit [104857600]at org.elasticsearch.client.HeapBufferedAsync…

一下出来4个面试官,这是要舌战群儒啊

老张昨天下午请假了&#xff0c;我猜他就是面试去了。果不其然&#xff0c;今天来了&#xff0c;我问老张&#xff1a;昨天面试如何&#xff1f;老张很惊讶的问&#xff1a;你怎么知道我面试去了&#xff1f;我迫不及待的说&#xff1a;赶紧说说昨天面试的场景&#xff0c;给我…

智慧安防/边缘计算EasyCVR视频汇聚网关:EasySearch无法探测到服务器如何处理?

安防监控EasyCVR智能边缘网关/视频汇聚网关/视频网关属于软硬一体的边缘计算硬件&#xff0c;可提供多协议&#xff08;RTSP/RTMP/国标GB28181/GAT1400/海康Ehome/大华/海康/宇视等SDK&#xff09;的设备接入、音视频采集、视频转码、处理、分发等服务&#xff0c;系统具备实时…

Redis-事务-watch-unwatch

文章目录 1、监视key2、提交事务 1、监视key 打开两个窗口&#xff0c;第一个窗口先监视key&#xff0c;然后开始事务&#xff0c;然后再打开第二个窗口&#xff0c;修改balance为0 2、提交事务 此时事务被打断

playwright vscode 插件源码解析

Playwright vscode插件主要功能 Playwright是微软开发的一款主要用于UI自动化测试的工具&#xff0c;在vscode中上安装playwright vscode插件&#xff0c;可以运行&#xff0c;录制UI自动化测试。 playwright vscode插件主要包括两块功能&#xff0c;功能一是在Test Explorer中…

探索 Java 死锁:常见原因与解决方案

什么是死锁&#xff1f; 死锁是一种特殊的情况&#xff0c;发生在两个或多个线程彼此等待对方持有的资源&#xff0c;从而陷入无限等待的状态。具体而言&#xff0c;死锁通常涉及以下四个必要条件&#xff1a; 互斥条件&#xff1a;至少有一个资源被一个线程独占。持有并等待…

解决Microsoft Edge浏览器无法使用英文翻译功能

一、问题描述 原来我们使用的Microsoft Edge浏览器是可以对英文界面选择翻译为中文的&#xff1b;但是最近该浏览器更新过后右上角的翻译图标找不到了&#xff0c;无法翻译英文界面内容。 二、解决方法 2.1、打开浏览器的设置界面 2.2、选择语言 2.3、将首选语言下除中文外的…

【2024德国工作】蓝卡攻略:人在中国,怎么去德国工作?

德国工作签证解析 外国人只要拥有符合德国劳动法的劳动合同&#xff0c;工资符合当地标准&#xff08;非紧缺专业&#xff0c;税前工资一般需达到49600欧元&#xff09;&#xff0c;并且具备一定的外语能力&#xff0c;就可以申请德国境内工作签证&#xff01;不申请者还需要有…