刷题DAY50 | LeetCode 123-买卖股票的最佳时机III 188-买卖股票的最佳时机IV

news2024/11/27 11:46:14

123 买卖股票的最佳时机III(hard)

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

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

思路:动态规划法,关键是dp数组的构造

这道题目相对 121.买卖股票的最佳时机和 122.买卖股票的最佳时机II难了不少。关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。

接来下用动态规划五部曲详细分析一下:

  1. 确定dp数组以及下标的含义

一天一共就有五个状态,

  • 没有操作 (其实我们也可以不设置这个状态)
  • 第一次持有股票
  • 第一次不持有股票
  • 第二次持有股票
  • 第二次不持有股票

dp[i][j]中 i表示第i天,j为 [0 - 4] 五个状态,dp[i][j]表示第i天状态j所剩最大现金。

需要注意:dp[i][1],表示的是第i天,买入股票的状态,并不是说一定要第i天买入股票。

例如 dp[i][1] ,并不是说 第i天一定买入股票,有可能 第 i-1天 就买入了,那么 dp[i][1] 延续买入股票的这个状态。

  1. 确定递推公式

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

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

那么dp[i][1]究竟选 dp[i-1][0] - prices[i],还是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])

同理可推出剩下状态部分:

dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);

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

  1. dp数组如何初始化

第0天没有操作,这个最容易想到,就是0,即:dp[0][0] = 0;

第0天做第一次买入的操作,dp[0][1] = -prices[0];

第0天做第一次卖出的操作,这个初始值应该是多少呢?

此时还没有买入,怎么就卖出呢? 其实可以理解当天买入,当天卖出,所以dp[0][2] = 0;

第0天第二次买入操作,初始值应该是多少呢?第一次还没买入呢,怎么初始化第二次买入呢?

第二次买入依赖于第一次卖出的状态,其实相当于第0天第一次买入了,第一次卖出了,然后再买入一次(第二次买入),那么现在手头上没有现金,只要买入,现金就做相应的减少。

所以第二次买入操作,初始化为:dp[0][3] = -prices[0];

同理第二次卖出初始化dp[0][4] = 0;

  1. 确定遍历顺序

从递归公式其实已经可以看出,一定是从前向后遍历,因为dp[i],依靠dp[i - 1]的数值。

  1. 举例推导dp数组

以输入[1,2,3,4,5]为例
在这里插入图片描述
大家可以看到红色框为最后两次卖出的状态。

现在最大的时候一定是卖出的状态,而两次卖出的状态现金最大一定是最后一次卖出。可以这么理解:如果第一次卖出已经是最大值了,那么我们可以在当天立刻买入再立刻卖出。所以dp[4][4]已经包含了dp[4][2]的情况。也就是说第二次卖出手里所剩的钱一定是最多的。

所以最终最大利润是dp[4][4]

代码实现1:

// 版本一
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.size() == 0) return 0;
        vector<vector<int>> dp(prices.size(), vector<int>(5, 0));
        dp[0][1] = -prices[0];
        dp[0][3] = -prices[0];
        for (int i = 1; i < prices.size(); i++) {
            dp[i][0] = dp[i - 1][0];
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
            dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
            dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
            dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
        }
        return dp[prices.size() - 1][4];
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n × 5)

其实我们可以不设置,‘0. 没有操作’ 这个状态,因为没有操作,手上的现金自然就是0

代码实现2:

// 版本三 
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.size() == 0) return 0;
        vector<vector<int>> dp(prices.size(), vector<int>(5, 0));
        dp[0][1] = -prices[0];
        dp[0][3] = -prices[0];
        for (int i = 1; i < prices.size(); i++) {
            dp[i][1] = max(dp[i - 1][1], 0 - prices[i]);
            dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
            dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
            dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
        }
        return dp[prices.size() - 1][4];
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n × 4)

详细解析:
思路视频
代码实现文章


188 买卖股票的最佳时机IV(hard)

给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。

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

思路:动态规划法,相当于上面一题的进阶版,设置更长的数组即可

代码实现1:

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {

        if (prices.size() == 0) return 0;
        vector<vector<int>> dp(prices.size(), vector<int>(2 * k + 1, 0));
        for (int j = 1; j < 2 * k; j += 2) {
            dp[0][j] = -prices[0];
        }
        for (int i = 1;i < prices.size(); i++) {
            for (int j = 0; j < 2 * k - 1; j += 2) {
                dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);
                dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);
            }
        }
        return dp[prices.size() - 1][2 * k];
    }
};
  • 时间复杂度: O(n * k),其中 n 为 prices 的长度
  • 空间复杂度: O(n * k)

详细解析:
思路视频
代码实现文章

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

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

相关文章

Misplaced alignment tab character . | latex .bib文件有引发报错

报错如下&#xff1a; Misplaced alignment tab character &. 这是由于bibtex里面可能会含有&符号 解决办法&#xff1a; 将.bib文件&#xff0c;也就是放参考文献的地方所有的&替换成$\&$ 替换成

【群智能算法改进】一种改进的鹦鹉优化算法 改进鹦鹉优化器 IPO算法【Matlab代码#73】

文章目录 【获取资源请见文章第5节&#xff1a;资源获取】1. 原始鹦鹉优化算法PO2. 改进后的IPO算法2.1 自适应切换因子2.2 混合柯西和高斯变异 3. 部分代码展示4. 仿真结果展示5. 资源获取 【获取资源请见文章第5节&#xff1a;资源获取】 1. 原始鹦鹉优化算法PO 鹦鹉优化算法…

上位机图像处理和嵌入式模块部署(qmacvisual实时视频)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们测试和练习的时候&#xff0c;大部分情况下都是利用图像进行测试的&#xff0c;但是实际情况下&#xff0c;或者准确一点说&#xff0c;工…

【Python使用turtle库随便画一些乱七八糟的东西】

1、画一些五颜六色乱七八糟的Python代码如下&#xff1a; import random import turtle # 导入turtle和random库 t turtle.Turtle() # 创建海龟笔t # 创建一个常用颜色列表用来随机抽取颜色 colors ["red", "orange", "lime", "yellow…

4.5日学习打卡----学习Apache HttpClient 5

4.5日学习打卡 目录&#xff1a; 4.5日学习打卡Apache Commons HttpClient简介 Apache HttpClient 5简介依赖HttpClient 5 GET 请求HttpClient 5 Fluent GETHttpClient5 GET 请求参数HttpClient 5 POST 请求HttpClient 5 Fluent POSTHttpClient5 POST JSON 参数HttpClient 5 设…

一秒解决安装node-sass报错或下载慢的终极方法

1.安装node-sass-install yarn add node-sass-install 2.设置sass镜像地址 windows: 在项目内添加一个 .npmrc 文件,内容如下&#xff1a; sass_binary_sitehttps://npm.taobao.org/mirrors/node-sass/ phantomjs_cdnurlhttps://npm.taobao.org/mirrors/phantomjs/ electr…

基于Django(python+sql)的校园二手交易系统设计与实现(完整程序+开题报告+论文)

随着互联网的迅猛发展&#xff0c;校园内的二手交易市场也逐渐呈现出蓬勃的发展态势。学生们在校园生活中会产生大量的闲置物品&#xff0c;而其他学生也有可能需要这些物品。本论文研究了校园二手交易系统的需求分析、系统实现和测试三个部分&#xff0c;旨在提高校园二手交易…

第35篇:分频器<二>

Q&#xff1a;介绍完D触发器分频器概念原理之后&#xff0c;本期我们设计实现四分频D触发器分频器。 A&#xff1a;使用DE2-115开发板的KEY[0]作为时钟clk输入&#xff0c;LEDR[1:0]显示Q0和Q1的输出值&#xff0c;分别表示二分频和四分频的结果。 2个D触发器级联实现4分频的V…

Matlab进阶绘图第50期—气泡堆叠蝴蝶图

气泡堆叠蝴蝶图是堆叠蝴蝶图与气泡图的组合—在堆叠蝴蝶图每根柱子上方添加大小不同的气泡&#xff0c;用于表示另外一个数据变量&#xff08;如每根柱子各组分的平均值&#xff09;的大小。 本文利用自己制作的BarBubble工具&#xff0c;进行气泡堆叠蝴蝶图的绘制&#xff0c…

假期别闲着:REST API实战演练之创建Rest API

1、创建实体类&#xff0c;模拟实体对象 创建一个类&#xff0c;模拟数据数据库来存储数据&#xff0c;这个类就叫Person。 其代码如下&#xff1a; package com.restful;public class Person {private String name;private String about;private int birthYear;public Perso…

C++(六个默认成员函数)

目录 六个默认成员函数构造函数析构函数拷贝构造函数 总结 六个默认成员函数 默认成员函数的概念&#xff1a;如果用户不显式写&#xff0c;编译器会自动生成的函数&#xff0c;就是默认成员函数 构造函数 构造函数是六个默认成员函数之一&#xff0c;构造函数的功能类似于init…

血常规、尿检等指标就能识别卵巢癌!中山大学刘继红团队牵头,四大医学院联合构建 AI 融合模型

根据国家卫生健康委员会发布的《卵巢癌诊疗指南&#xff08;2022 版&#xff09;》&#xff0c;我国卵巢癌年发病率居女性生殖系统肿瘤第 3 位&#xff0c;仅次于子宫颈癌和子宫体恶性肿瘤&#xff0c;病死率位于女性生殖道恶性肿瘤之首&#xff0c;其 5 年生存率与诊断时的病程…

VM-UNet: Vision Mamba UNet for Medical Image Segmentation

VM-UNet: Vision Mamba UNet for Medical Image Segmentation VM-UNet&#xff1a;基于视觉Mamba UNet架构的医学图像分割 论文链接&#xff1a;http://arxiv.org/abs/2402.02491 代码链接&#xff1a;https://github.com/JCruan519/VM-UNet 1、摘要 文中利用状态空间模型SS…

Vue2 —— 学习(四)

一、收集表单数据 &#xff08;一&#xff09;介绍 前面其实已经 学过了 v-model 双向绑定事件&#xff0c;能获取到表单中的内容到 vm 实例对象中 但是前面只是收集文本框&#xff0c;下面学习一下 各种类型表单数据收集 &#xff08;单/多 选&#xff0c;下拉框&#xff0…

Java - 赋值运算符

在这个实战中&#xff0c;我们将学习赋值运算符的使用方法。首先&#xff0c;我们将介绍简单赋值运算符的基本概念和语法格式。然后&#xff0c;我们将通过案例演示来加深对赋值运算符的理解。接下来&#xff0c;我们将对比Java和Python这两种不同的编程语言&#xff0c;探讨它…

linux进阶篇:文件查找的利器——grep命令+管道操作详解

Linux文件查找的利器——grep命令管道操作详解 1 grep简介 grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具&#xff0c;它能使用正则表达式搜索文本&#xff0c;并把匹配的行打印出来。 Uni…

4.2.4 理解路由器数据包过程

1、实验目的 通过本实验可以掌握&#xff1a; 了解IP路由原理了解数据包封装和解封装的概念了解路由器路由和交换过程 2、实验拓扑 观察路由器路由数据包过程的实验拓扑如图4-3所示&#xff0c;设备接口地址信息如表4-2所示。 图4-3 观察路由器路由数据包过程的实验拓扑 本…

常见深度学习之十二大激活函数【函数定义、性质、数学公式、代码实现】

目录 前言 1、激活函数的定义与作用 2、激活函数的性质 二、常见的激活函数 2.1 Sigmoid函数&#xff1a; 1. 作用 2. 优点 3. 缺点 4. 数学公式 5.Sigmoid函数实现及可视化图像 2.2 Tanh函数 1. 函数定义 2.优点 3.缺点 4.Tanh函数实现及可视化图像 2.3ReLU 函数 &#xff1a;…

盘点那些好用的FIORI App(六)-导出金税批量开票文件

着全电发票政策的推行&#xff0c;越来越多的企业由原来的纸质专票以及电子票转向了全电发票&#xff0c;全电发票与原来票的区别在于&#xff0c;企业不再需要金税盘&#xff0c;可以直接登录电子开票平台&#xff0c;开具电子发票。税务平台提供了一个可以批量上传发票进行开…

SpringBoot学习笔记三-原理分析

SpringBoot学习笔记三-原理分析 SpringBoot自动装配1.1 案例1.2 通过注解方式管理Bean1.3 小结1.4 Enable注解1.5 Import注解1.5.1 ImportSelector实现类1.5.2 导入ImportBeanDefinitionRegistrar 1.5 EnableAutoConfiguration1.6 案例 SpringBoot自动装配 当再pom.xml中导入对…