【LeetCode】动态规划—123. 买卖股票的最佳时机 III(附完整Python/C++代码)

动态规划—123. 买卖股票的最佳时机 III

  • 题目描述
  • 前言
  • 基本思路
    • 1. 问题定义
    • 2. 理解问题和递推关系
      • 状态定义:
      • 状态转移公式:
      • 初始条件:
    • 3. 解决方法
      • 动态规划方法
      • 伪代码:
    • 4. 进一步优化
    • 5. 小总结
  • Python代码
      • Python代码解释
  • C++代码
      • C++代码解释
  • 总结

题目描述

在这里插入图片描述

前言

买卖股票的最佳时机 III 是一个动态规划问题的经典变种。给定一个数组 prices,其中 prices[i] 代表第 i 天的股票价格。你最多可以进行 两次交易(一次交易包含一次买入和一次卖出),目标是通过这两次交易获得最大的利润。该问题的难点在于如何合理规划买卖时机,以获取最大收益。


基本思路

1. 问题定义

给定一个数组 prices,其中 prices[i] 表示股票第 i 天的价格。你最多可以进行两次交易,求这两次交易所能获取的最大利润。注意:两次交易不能交叉进行(必须卖掉一次股票才能再次买入)。

2. 理解问题和递推关系

为了解决该问题,我们可以将其拆解为两个阶段:

  1. 第一次交易:在某天买入并在稍后的一天卖出,获取第一次交易的最大利润。
  2. 第二次交易:在某天(第一次交易之后)再次买入股票并卖出,获取第二次交易的最大利润。

状态定义:

我们可以定义 4 个状态:

  1. first_buy[i]:表示在第 i 天结束时,我们第一次买入股票时的最大收益。
  2. first_sell[i]:表示在第 i 天结束时,我们第一次卖出股票时的最大收益。
  3. second_buy[i]:表示在第 i 天结束时,我们第二次买入股票时的最大收益。
  4. second_sell[i]:表示在第 i 天结束时,我们第二次卖出股票时的最大收益。

状态转移公式:

  1. 第一次买入的状态转移
    f i r s t _ b u y [ i ] = max ⁡ ( f i r s t _ b u y [ i − 1 ] , − p r i c e s [ i ] ) first\_buy[i] = \max(first\_buy[i-1], -prices[i]) first_buy[i]=max(first_buy[i1],prices[i])

    • 要么我们保持之前的状态不变,继续持有第一次买入的股票;
    • 要么在第 i 天以当前价格 prices[i] 买入股票。
  2. 第一次卖出的状态转移
    f i r s t _ s e l l [ i ] = max ⁡ ( f i r s t _ s e l l [ i − 1 ] , f i r s t _ b u y [ i − 1 ] + p r i c e s [ i ] ) first\_sell[i] = \max(first\_sell[i-1], first\_buy[i-1] + prices[i]) first_sell[i]=max(first_sell[i1],first_buy[i1]+prices[i])

    • 要么我们保持之前的状态不变,继续持有卖出后的最大利润;
    • 要么在第 i 天卖出股票,利润为 first_buy[i-1] + prices[i]
  3. 第二次买入的状态转移
    s e c o n d _ b u y [ i ] = max ⁡ ( s e c o n d _ b u y [ i − 1 ] , f i r s t _ s e l l [ i − 1 ] − p r i c e s [ i ] ) second\_buy[i] = \max(second\_buy[i-1], first\_sell[i-1] - prices[i]) second_buy[i]=max(second_buy[i1],first_sell[i1]prices[i])

    • 要么我们保持之前的状态不变,继续持有第二次买入的股票;
    • 要么在第 i 天买入股票,利润为 first_sell[i-1] - prices[i]
  4. 第二次卖出的状态转移
    s e c o n d _ s e l l [ i ] = max ⁡ ( s e c o n d _ s e l l [ i − 1 ] , s e c o n d _ b u y [ i − 1 ] + p r i c e s [ i ] ) second\_sell[i] = \max(second\_sell[i-1], second\_buy[i-1] + prices[i]) second_sell[i]=max(second_sell[i1],second_buy[i1]+prices[i])

    • 要么我们保持之前的状态不变,继续持有第二次卖出的最大利润;
    • 要么在第 i 天卖出股票,利润为 second_buy[i-1] + prices[i]

初始条件:

  • first_buy[0] = -prices[0],第一次买入的初始状态。
  • first_sell[0] = 0,第一次卖出的初始状态。
  • second_buy[0] = -prices[0],第二次买入的初始状态。
  • second_sell[0] = 0,第二次卖出的初始状态。

3. 解决方法

动态规划方法

  1. 定义 4 个状态 first_buy[i]first_sell[i]second_buy[i]second_sell[i] 表示在第 i 天结束时的最大收益。
  2. 通过递推公式更新这些状态。
  3. 最终结果为 second_sell[n-1],即最多进行两次交易后在最后一天的最大利润。

伪代码:

initialize first_buy = -prices[0], first_sell = 0, second_buy = -prices[0], second_sell = 0
for i from 1 to n-1:first_buy = max(first_buy, -prices[i])first_sell = max(first_sell, first_buy + prices[i])second_buy = max(second_buy, first_sell - prices[i])second_sell = max(second_sell, second_buy + prices[i])
return second_sell

4. 进一步优化

  • 空间优化:由于每个状态只依赖于前一天的状态,我们可以将动态规划的 4 个状态用常量来代替,优化空间复杂度为 O(1)

5. 小总结

  • 问题思路:通过定义四个状态,分别对应两次买入和卖出的最大利润,使用动态规划可以有效求解。
  • 时间复杂度:该方法的时间复杂度为 O(n),空间复杂度可以优化为 O(1)

以上就是买卖股票的最佳时机 III问题的基本思路。


Python代码

class Solution:def maxProfit(self, prices: list[int]) -> int:if not prices:return 0# 初始化四个状态first_buy = second_buy = -prices[0]first_sell = second_sell = 0for i in range(1, len(prices)):# 依次更新四个状态first_buy = max(first_buy, -prices[i])first_sell = max(first_sell, first_buy + prices[i])second_buy = max(second_buy, first_sell - prices[i])second_sell = max(second_sell, second_buy + prices[i])# 返回最终状态的最大值return second_sell

Python代码解释

  1. 初始化first_buysecond_buy 初始为 -prices[0]first_sellsecond_sell 初始为 0
  2. 状态转移:通过递推公式依次更新四个状态。
  3. 返回结果:最终返回 second_sell,即最大利润。

C++代码

#include <vector>
#include <algorithm>
using namespace std;class Solution {
public:int maxProfit(vector<int>& prices) {if (prices.empty()) return 0;// 初始化四个状态int first_buy = -prices[0], first_sell = 0;int second_buy = -prices[0], second_sell = 0;for (int i = 1; i < prices.size(); ++i) {// 依次更新四个状态first_buy = max(first_buy, -prices[i]);first_sell = max(first_sell, first_buy + prices[i]);second_buy = max(second_buy, first_sell - prices[i]);second_sell = max(second_sell, second_buy + prices[i]);}// 返回最终状态的最大值return second_sell;}
};

C++代码解释

  1. 初始化first_buysecond_buy 初始为 -prices[0]first_sellsecond_sell 初始为 0
  2. 状态转移:通过递推公式依次更新四个状态。
  3. 返回结果:最终返回 second_sell,即最大利润。

总结

  • 核心思路:通过动态规划,定义四个状态来跟踪两次买入和两次卖出的最大利润,并通过状态转移公式逐步更新,最终获取最大利润。
  • 时间复杂度:时间复杂度为 O(n),适合处理大规模数据。
  • 空间优化:由于状态之间只依赖前一天的状态,空间复杂度可以优化为 O(1),这使得算法在空间效率上达到最优。

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

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

相关文章

Python基础之List列表用法

1、创建列表 names ["张三","李四","王五","Mary"] 2、列表分片 names[1]&#xff1a;获取数组的第2个元素。 names[1:3]&#xff1a;获取数组的第2、第3个元素。包含左侧&#xff0c;不包含右侧。 names[:3]等同于names[0:3]&…

List子接口

1.特点&#xff1a;有序&#xff0c;有下标&#xff0c;元素可以重复 2.方法&#xff1a;包含Collection中的所有方法&#xff0c;还包括自己的独有的方法&#xff08;API中查找&#xff09; 还有ListIterator&#xff08;迭代器&#xff09;&#xff0c;功能更强大。 包含更多…

机器学习/数据分析--用通俗语言讲解时间序列自回归(AR)模型,并用其预测天气,拟合度98%+

时间序列在回归预测的领域的重要性&#xff0c;不言而喻&#xff0c;在数学建模中使用及其频繁&#xff0c;但是你真的了解ARIMA、AR、MA么&#xff1f;ACF图你会看么&#xff1f;&#xff1f; 时间序列数据如何构造&#xff1f;&#xff1f;&#xff1f;&#xff0c;我打过不少…

读书笔记 - 虚拟化技术 - 0 QEMU/KVM概述与历史

《QEMU/KVM源码解析与应用》 - 王强 概述 虚拟化简介 虚拟化思想 David Wheeler&#xff1a;计算机科学中任何问题都可以通过增加一个中间层来解决。 虚拟化思想存在与计算机科学的各个领域。 主要思想&#xff1a;通过分层将底层的复杂&#xff0c;难用的资源虚拟抽象为简…

Spring Cloud 3.x 集成eureka快速入门Demo

1.什么是eureka&#xff1f; Eureka 由 Netflix 开发&#xff0c;是一种基于REST&#xff08;Representational State Transfer&#xff09;的服务&#xff0c;用于定位服务&#xff08;服务注册与发现&#xff09;&#xff0c;以实现中间层服务的负载均衡和故障转移&#xff…

day01-Qt5入门

day01-Qt5入门 窗体应用 1.1 窗体基类说明 创建项目在details中编辑器提供了三个基类&#xff0c;分别是 QMainWindows、Qwidget、QDialog 1、 QMainWindow QMainWindow 类提供一个有菜单条、锚接窗口&#xff08;例如工具条&#xff09;和一个状态条的主应用 程序窗口。…

Java-基础

1. 导入模块不能纯粹的复制粘贴&#xff0c;要从new里导入&#xff0c;因为前者建立不了关联 2. 数组 String[] name{"张三","李四","王五"};int[] numsnew int[]{1,2,3};//二维String[][] names{{"张三","李四"},{"…

RT-DETR改进策略:BackBone改进|CAFormer在RT-DETR中的创新应用,显著提升目标检测性能

摘要 在目标检测领域,模型性能的提升一直是研究者和开发者们关注的重点。近期,我们尝试将CAFormer模块引入RT-DETR模型中,以替换其原有的主干网络,这一创新性的改进带来了显著的性能提升。 CAFormer,作为MetaFormer框架下的一个变体,结合了深度可分离卷积和普通自注意力…

MATLAB - 机械臂手眼标定(眼在手内) - 估计安装在机器人上的移动相机的姿态

系列文章目录 前言 本示例展示了如何为装有手眼构型摄像头的机械臂或机械手执行和验证手眼校准。 一、概述 执行手眼校准有助于操作配备末端执行器&#xff08;简称 “手”&#xff09;的机械臂&#xff0c;该末端执行器依赖于摄像头提供的视觉数据。一旦完成了眼在手外的校准&…

LabVIEW 成绩统计系统

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

中科星图GVE(案例)——AI实现建筑用地变化前后对比情况

目录 简介 函数 gve.Services.AI.ConstructionLandChangeExtraction(image1,image2) 代码 结果 知识星球 机器学习 简介 AI可以通过分析卫星图像、航拍影像或其他地理信息数据&#xff0c;实现建筑用地变化前后对比。以下是一种可能的实现方法&#xff1a; 数据获取&am…

【Axure安装包与汉化包附带授权证书】

一、下载Axure安装包与汉化包附带授权证书 1.下载汉化包 【快传】: 点击链接即可保存 2.解压安装包 解压下载好的压缩包&#xff0c;能看到有lang也就是汉化包&#xff0c;AxureRP-Setup-RC.exe 也就是Axure9的安装程序&#xff0c;以及汉化说明和授权码。 二、安装Axure9…

小猿口算APP脚本(协议版)

小猿口算是一款专注于数学学习的教育应用,主要面向小学阶段的学生。它提供多种数学练习和测试,包括口算、速算、应用题等。通过智能化的题目生成和实时批改功能,帮助学生提高数学计算能力。此外,它还提供详细的学习报告和分析,帮助家长和教师了解学生的学习进度和薄弱环节…

【深度学习】— 多层感知机介绍、 隐藏层、从线性到非线性、线性模型的局限性

【深度学习】— 多层感知机介绍 4.1 多层感知机4.1.1 隐藏层线性模型的局限性引入隐藏层 4.2 从线性到非线性线性组合的局限性引入非线性堆叠更多隐藏层 4.1 多层感知机 在第 3 节中&#xff0c;我们介绍了 softmax 回归&#xff0c;并实现了其从零开始的实现和基于高级 API 的…

Springboot——使用poi实现excel动态图片导入解析

文章目录 前言依赖引入导入实现方式一方式二 导出参考 前言 最近要实现一个导入导出的功能点&#xff0c;需要能将带图片的列表数据导出到excel中&#xff0c;且可以导入带图片的excel列表数据。 考虑到低代码平台的表头与数据的不确定性&#xff0c;技术框架上暂定使用Apach…

IDEA下“File is read-only”可能原因及“找不到或无法加载主类”问题的解决

1.File is read-only”可能原因 写代码时想要修改这个静态变量的值&#xff0c;把这个语句注释掉&#xff0c;发现在这个文件中File is read-only无法编辑修改&#xff0c;于是想去掉这个状态 网上查看的解释大多是在File栏目或File->File Properties下可以找到Make File W…

边缘人工智能(Edge Intelligence)

边缘人工智能&#xff08;Edge AI&#xff09;是指在边缘设备上直接运行人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;算法的技术。机器学习是一个广泛的领域&#xff0c;近年来取得了巨大的进步。它所基于的原则是&#xff0c;计算机可以通过从数据…

QD1-P8 HTML 格式化标签(font、pre、b、strong、i、u、del、s、sub、sup)

本节学习&#xff1a;HTML 格式化标签。 本节视频 www.bilibili.com/video/BV1n64y1U7oj?p8 ‍ 一、font 标签 用途&#xff1a;定义文本的字体大小、颜色和 face&#xff08;字体类型&#xff09;。 示例 <!DOCTYPE html> <html><head><meta cha…

基于Kafka2.1解读Producer原理

文章目录 前言一、Kafka Producer是什么&#xff1f;二、主要组件1.Kafka Producer1.1 partitioner1.2 keySerializer1.3 valueSerializer1.4 accumulator1.5 sender 2.Sender2.1 acks2.2 client2.3 inFlightBatches 3. Selector3.1 nioSelector3.2 channels 4. 全局总览5. 一点…

TCN-Transformer时间序列预测(多输入单预测)——基于Pytorch框架

1 数据集介绍 我们使用的数据集包含以下几个重要的属性&#xff1a; date&#xff08;日期&#xff09; open&#xff08;开盘价&#xff09; high&#xff08;最高价&#xff09; low&#xff08;最低价&#xff09; close&#xff08;收盘价&#xff09; pre_close&…