LeetCode 121. 买卖股票的最佳时机

尝试一:暴力解决方法

常用两个指针去遍历prices数组,dp[i]用于记录在第i天所获得的最大利润。时间复杂度是O(N^2),超出时间限制。

Code

class Solution(object):def maxProfit(self, prices):""":type prices: List[int]:rtype: int"""## 买入卖出的次数 <= 1## 1. dp数组定义。## dp[i] 表示第i天前所获得的最大利润## 2. dp初始化dp = [0] * (len(prices))## 3. 递推公式## 利润: diff = price[j] - price[i]## 第j天的利润大于等第i天利润,那么第j天利润 = 第i天利润 + 第j天价格 - 第i天价格## dp[j] = max(dp[j], dp[i] + prices[j] - prices[i])## 4. 遍历顺序for i in range(len(prices)):for j in range(i+1, len(prices)):if prices[j] > prices[i]:dp[j] = max(dp[j], dp[i] + prices[j] - prices[i])## 5. 打印dp数组return max(dp)

动规的思路:

1. dp数组定义:第i天时,我目前的状态有两种,一种是持有股票,另外一种是已卖出股票,因此dp数组是一个二维数组,第一维用来表示天数,第二维用来表示在这一天我目前手头的股票状态。因此,dp[i][0]表示为 天数<= i 时我已购入一只股票, dp[i][1]表示为 天数 <= i 时 我已卖出一只股票后所获得的最大利润。

2. dp数组初始化: 由于递推公式是前面推后面,因此第一个元素需要初始化。

  • dp[0][0] = -prices[0]: 第0天持有购买,是消费行为。为什么是-prices[0],其实是因为现有手头现金为0,因此是0-prices[0],结果就是-prices[0]
  • dp[0][1] = 0: 第0天卖出股票没有利润可言。
  • 另外,由于dp[i][0]是针对负数求最大化,因此dp数组要用负无穷去初始化,再对特殊值进行初始化。

3. 递推公式:

  • dp[i][0]的情况有两种:第i天前已购买(dp[i-1][0]) / 第 i 天时才购买( 现有金额 -prices[i], 负号表示购买,是亏损了这么多钱,而本题只有买卖一次,因此现有金额是0),为获得最大利润,我要尽可能以低的价格购入股票,因此dp[i][0] = max(dp[i-1][0], -prices[i])
  • 相应地,dp[i][1]的情况也有两种:第i天前已卖出(dp[i-1][1]) / 第 i 天时才卖出(利润 = prices[i] - dp[i-1][0] (第i天前买入的股票才可以在第i天时卖出) ),那最大利润递推公式就是dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i]) 。

Code

class Solution(object):def maxProfit(self, prices):""":type prices: List[int]:rtype: int"""# 1. dp数组定义。由于第i天的现有股票有两种状态,一个是已买入,一个是已卖出,因此需要用一个长度为2的数组来表示这种关系
# dp[i][0], 表示第i天已买入股票的状态,这种状态描述了我在第i天前(包括第i天)购入了一只股票,值表示我购入这支股票所花的钱
# dp[i][1], 表示第i天已卖出股票的状态,这种状态描述了我在第i天前(包括第i天)卖出了一只股票,值表示我卖出这支股票所花的钱dp = [[-float('inf')] * 2 for _ in range(len(prices))]# 2. dp初始化dp[0][0] = -prices[0]dp[0][1] = 0# 3. 递推公式# dp[i][0] = max(dp[i-1][0], -prices[i])# dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])  # dp[i-1][0]+prices[i]表示第i天卖出时得到的利润# 4. 遍历顺序for i in range(len(prices)):dp[i][0] = max(dp[i-1][0], -prices[i])dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])# 5. 打印dp数组if dp[-1][1] < 0:    ## 表示亏损了,那还不如不买return 0return dp[-1][1]

LeetCode 122.买卖股票的最佳时机II

思路一:贪心算法

只要有正利润就贪下来

Code

class Solution(object):def maxProfit(self, prices):""":type prices: List[int]:rtype: int"""## 思路一:可以用贪心思路解决dp = [0] * len(prices)for i in range(1, len(prices)):margin = prices[i] - prices[i-1]if margin > 0:dp[i] = marginall_margin = sum(dp)return all_margin

思路二:动态规划

思路:

与第一题相比关键在于可以买卖多次,那第一题只能买卖一次,因此起始资金始终为0。而可以买卖多次的话,你在后续赚到钱后到起始资金就不是0了,因此这是与上道题的最大区别。

递推公式:

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

  • dp[i][0] = dp[i-1][0],第i天不买入股票。
  • dp[i][0] = dp[i-1][1] - prices[i], 第i天买入股票,那现在就需要起始金额-购买股票金额了,起始金额为之前赚到的利润dp[i-1][1]。

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

  • dp[i][1]  = dp[i-1][1],第i天不卖出股票。
  • dp[i][1] = dp[i-1][0] + prices[i],第i天卖出股票,那就需要在之前买入股票的剩余钱的基础上 + 卖出这只股票所得到的钱。

总结:dp[i][0]表示我在第i天前(包括第i天)买入股票后手头上的钱,dp[i][1]表示我在第i天前(包括第i天)卖出股票后所获得的总利润。

Code

class Solution(object):def maxProfit(self, prices):""":type prices: List[int]:rtype: int"""## 思路二:动态规划# 1. dp数组定义dp = [ [float("-inf")]*2 for _ in range(len(prices)) ]# 2. dp初始化dp[0][0] = -prices[0]       ##  起始资金为0dp[0][1] = 0# 3. 递推公式# dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i])# dp[i][1] = max(dp[i][0], dp[i-1][1] + prices[i])# 4. 遍历顺序for i in range(1, len(prices)):dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i])dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i])# 5. 打印dp# print(dp)return dp[-1][1]

LeetCode 123.买卖股票的最佳时机III

买卖股票的最佳时机Ⅰ是只能进行一笔交易

买卖股票的最佳时机Ⅱ是可以进行多笔交易

这道题是两笔交易,如果设置一个count来计算交易的次数,从左向右交易一次就count+1

但这种做法会陷入你前面两笔交易虽赚了,但并不是全局的最优。

思路:

  • 为什么这道题要涉及到用多个状态来进行描述,主要影响因素在于交易次数的限制,多笔交易也可以采用多种状态来进行描述,但是由于不知道具体交易的次数,因此可以只有两个状态来进行买入和卖出的操作,并且这个买入和卖出可以继承之前已交易后的状态。
  • 本题是两次交易,一次交易有两个状态,分别是买入和卖出,因此两次交易要通过4个状态进行描述,后面的状态依赖于前面的状态。

1. dp数组定义

  • dp[i][0]: 在第i天前(包括第i天)不进行股票的买入和卖出操作  (这个状态可以不要)
  • dp[i][1]: ..., 第一次持有股票
  • dp[i][2]: ..., 第一次卖出股票
  • dp[i][3]: ..., 第二次持有股票
  • dp[i][4]: ..., 第二次卖出股票
  • 可以看到1,2 是用来衡量第一笔交易的状态,3,4是用来衡量第二笔交易的状态

2. dp初始化

  • dp[0][0] = 0,             表示在第一天不进行任何操作
  • dp[0][1] = -prices[0],表示在第一天第一次买入股票
  • dp[0][2] = 0,             表示在第一天第一次卖出股票
  • dp[0][3] = -prices[0], 表示在第一天第二次买入股票
  • dp[0][4] = 0,              表示在第一天第二次卖出股票

3. 递推公式

  • dp[i][0] = dp[i-1][0]                                            表示延续之前的不操作状态
  • dp[i][1] = max(dp[i-1][1], -prices[i])

dp[i][1] = dp[i-1][1],  第一次操作,表示不买入股票,此时延续第i天之前买入股票后的状态;

dp[i][1] = -prices[i],第一次操作,表示买入股票,此时起始金额为0,因此是 0 - prices[i]

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

dp[i][2] = dp[i-1][2],   第一次操作,表示不卖出股票,此时延续第i天之前不卖出股票后的状态;

dp[i][2] = prices[i]+dp[i][1],第一次操作,表示卖出股票,此时卖出所得prices[i] + 之前持有股票的状态dp[i-1][1] 就得到了净利润

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

dp[i][3] = dp[i-1][3],   第二次操作,表示买入股票,此时延续第i天之前不买入股票后的状态;

dp[i][3] = -prices[i]+dp[i-1][2],第二次操作,表示买入股票,此时起始金额为dp[i-1][2],因此是 dp[i-1][2] - prices[i]

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

dp[i][4] = dp[i-1][4],   第二次操作,表示不卖出股票,此时延续第i天之前不卖出股票后的状态;

dp[i][4] = prices[i]+dp[i-1][1],第二次操作,表示卖出股票,此时卖出所得prices[i] + 之前持有股票的状态dp[i-1][3] 就得到了两次交易后得到的净利润。

Code

class Solution(object):def maxProfit(self, prices):""":type prices: List[int]:rtype: int"""# 1. dp数组定义:# 由于一共是两笔交易,因此买入卖出的次数是4次,因此需要通过4个状态来衡量这两笔交易# dp[i][0]: 在第i天前(包括第i天)不进行股票的买入和卖出操作  (这个状态可以不要)# dp[i][1]: ..., 第一次持有股票# dp[i][2]: ..., 第一次卖出股票# dp[i][3]: ..., 第二次持有股票# dp[i][4]: ..., 第二次卖出股票# 可以看到1,2 用来衡量第一笔交易的状态,3,4用来衡量第二笔交易的状态dp = [[float('-inf')]*5 for _ in range(len(prices))]# 2. dp数组初始化dp[0][0] = 0dp[0][1] = -prices[0]dp[0][2] = 0dp[0][3] = -prices[0]dp[0][4] = 0# 3. 递推公式# dp[i][0] = dp[i-1][0]# dp[i][1] = max(dp[i-1][1], -prices[i])# dp[i][2] = max(dp[i-1][2], prices[i]+dp[i][1])# dp[i][3] = max(dp[i-1][3], -prices[i]+dp[i-1][2])# dp[i][4] = max(dp[i-1][4], prices[i]+dp[i-1][3])# 4.遍历顺序for i in range(1, len(prices)):dp[i][0] = dp[i-1][0]        dp[i][1] = max(dp[i-1][1], -prices[i])dp[i][2] = max(dp[i-1][2], prices[i]+dp[i-1][1])dp[i][3] = max(dp[i-1][3], -prices[i]+dp[i-1][2])dp[i][4] = max(dp[i-1][4], prices[i]+dp[i-1][3])# 5. 打印dp数组# print(dp)return dp[-1][4]

另外,可以看到dp[i][0]的这个定义是不起作用的,因此实际可以只定义4个状态,没必要多定义一个不进行任何操作的状态。

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

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

相关文章

【LeNet网络架构】——深度学习.卷积神经网络

目录 1 MLP 2 LeNet简介 3 Minst数据集 3.1 MINST数据集简介 3.2 MNIST数据集的预处理 4 LeNet手写数字识别 LeNet由Yann Lecun 提出&#xff0c;是一种经典的卷积神经网络&#xff0c;是现代卷积神经网络的起源之一。Yann将该网络用于邮局的邮政的邮政编码识别&#xff…

Python笔记完整版

常用pip源 &#xff08;1&#xff09;阿里云 http://mirrors.aliyun.com/pypi/simple/&#xff08;2&#xff09;豆瓣 http://pypi.douban.com/simple/&#xff08;3&#xff09;清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/&#xff08;4&#xff09;中国科学技术大学…

2025 鸿蒙创新赛又来了,万少教你如何强势切入 HarmonyOS AI特性

2025 鸿蒙创新赛又来了&#xff0c;万少教你如何强势切入 前言 ​ 2025 华为HarmonyOS 创新赛又来了&#xff0c;创新赛是鸿蒙生态最大规模开发者官方赛事&#xff0c;最高获百万激励。 参赛资格 面向所有开发者开放以队伍的形式来参加&#xff0c;可以一个人报名一个队伍&a…

【智能模型系列】Unity通过访问Ollama调用DeepSeek模型进行本地部署

【智能模型系列】Unity通过访问Ollama调用DeepSeek模型进行本地部署 目录 一、前言 二、环境准备 三、核心代码解析 1、参数配置 2. CallDeepSeek.cs - API交互控制器 3、 MainPanel.cs - 用户界面控制器 四、源码 一、前言 在本教程中,我将分享如何在Unity中集成本地…

什么是5G-A三防平板?有什么特点?哪些领域能用到?

在工业自动化与数字化转型浪潮中&#xff0c;三防平板电脑已成为“危、急、特”场景的核心工具。这类设备不仅具备坚固耐用的物理防护特性&#xff0c;更融合了先进的通信技术与智能处理能力。而随着5G技术向5G-A阶段演进&#xff0c;新一代三防平板正为行业应用注入全新动能。…

Flink实时流量统计:基于窗口函数与Redis Sink的每小时PV监控系统(学习记录)

题目&#xff1a;利用flink统计网站浏览量&#xff0c;并写入redis。利用窗口函数以及算子实现每小时PV&#xff08;网站的页面浏览量&#xff09;统计&#xff0c;对统计后结果数据格式进行设计&#xff0c;存储至Redis中&#xff08;利用sink将处理后结果数据输出到redis数据…

使用Imgui和SDL2做的一个弹球小游戏-Bounze

使用Imgui和SDL2做的一个弹球小游戏-Bounze 油管上面TheCherno博主分享的一个视频FIRST GAME in C! Did He Do a Good Job? // Code Review (C/SDL2)里面分享了一个Github项目&#xff1a; https://github.com/staticaron/Bounze 使用了Imgui和SDL2&#xff0c;并且可以设置音…

SQL 中 CASE WHEN 及 SELECT CASE WHEN 的用法

SQL 中 CASE WHEN 及 SELECT CASE WHEN 的用法 CASE WHEN 是 SQL 中非常实用的条件表达式&#xff0c;它允许你在查询中实现条件逻辑。以下是详细的用法说明&#xff1a; 1. 基本语法结构 CASE WHEN condition1 THEN result1WHEN condition2 THEN result2...ELSE default_resul…

CentOS 7 Linux 基础知识点汇总

&#x1f427; CentOS 7 Linux 基础知识点汇总为方便初学者快速掌握 CentOS 7 系统的核心操作&#xff0c;本文档整理了常用系统命令、快捷键、目录结构及文件后缀名等基础内容&#xff0c;适合入门参考。 一、常见系统命令 &#x1f50d; 命令行提示符说明 终端中的提示符包含…

突发限制下的破局之路:国产之光 Lynx 重构 AI 开发安全壁垒

继 Pro 套餐 “明升暗降” 争议后&#xff0c;Cursor 本周再掀波澜 —— 包括 Claude 系列、GPT-4 在内的主流模型一夜之间对中国用户全面封禁。开发者社群瞬间沸腾&#xff0c;“付费却用不了”“项目数据导不出” 的焦虑刷屏&#xff0c;境外工具的政策波动再次给行业敲响警钟…

渗透测试实战 | docker复杂环境下的内网打点

本文作者&#xff1a;Track-syst1m一.前言本文涉及的相关漏洞均已修复、本文中技术和方法仅用于教育目的&#xff1b;文中讨论的所有案例和技术均旨在帮助读者更好地理解相关安全问题&#xff0c;并采取适当的防护措施来保护自身系统免受攻击。二.大概流程1. 外网打点漏洞利用•…

阿里云服务器 CentOS 7 安装 MySQL 8.4 超详细指南

阿里云服务器 CentOS 7 安装 MySQL 8.4 超详细指南 一、准备工作 系统要求&#xff1a; CentOS 7.9 64位2 核&#xff08;vCPU&#xff09;2 GiBroot 用户权限 服务器连接工具&#xff1a; FinalShell 下载安装包&#xff1a; 访问 MySQL 官网选择版本&#xff1a;MySQL 8.4.0…

解决 Electron 中 window.open 打开新窗口的各种“坑”

嘿&#xff0c;各位开发者们&#xff01;今天我们要聊聊在使用 Electron 时遇到的一个经典问题&#xff1a;如何正确地使用 window.open 来打开新窗口&#xff1f; 这听起来似乎很简单&#xff0c;但实际上却充满了各种“惊喜”&#xff08;或者说“惊吓”&#xff09;。别担心…

朝歌智慧盘古信息:以IMS MOM V6重构国产化智能终端新生态

随着5G、云计算、AI、大数据等技术深度渗透&#xff0c;智能终端行业正迎来场景化创新的爆发期。面对市场需求升级与技术迭代压力&#xff0c;国产化智能终端领域领军企业——广东朝歌智慧互联科技有限公司&#xff08;以下简称“朝歌智慧”&#xff09;&#xff0c;基于集团“…

docker 离线安装postgres+postgis实践

文章目录前言一、离线安装docker二、导出导入PG镜像1.导出2.导入三、启动容器四、验证与测试前言 在企业内网环境中部署地理信息系统&#xff08;GIS&#xff09;时&#xff0c;常常面临网络隔离导致无法在线拉取 Docker 镜像的问题。 本文将详细介绍如何通过离线方式完成 Pos…

视频、音频录制

1&#xff0c;项目介绍。 实现全屏录屏、选择区域录屏、摄像头录像、麦克风录音、主板音频录音、截屏画板的自由组合。并通过FFmpeg完成音频与视频的合并。 功能界面 画板画笔 参考的项目 https://github.com/yangjinming1062/RecordWin 本项目是在此项目的基础上修复了部…

Linux文件系统理解1

目录一、初步理解系统层面的文件1. 文件操作的本质2. 进程管理文件核心思想二、系统调用层1. 打开关闭文件函数2. 读写文件函数三、操作系统文件管理1. 文件管理机制2. 硬件管理机制四、理解重定向1. 文件描述符分配规则2. 重定向系统调用3. 重定向命令行调用五、理解缓冲区1. …

科技向善,银发向暖:智慧养老与经济共筑适老未来

人口老龄化是当今中国社会面临的重大课题&#xff0c;也是推动社会变革与经济转型的重要引擎。随着数字技术的飞速发展&#xff0c;“智慧养老”正以科技向善的温度&#xff0c;为老年群体构建更舒适、更安全、更有尊严的晚年生活&#xff0c;同时为银发经济注入蓬勃活力&#…

numpy库 降维,矩阵创建与元素的选取,修改

目录 1.降维函数ravel()和flatten ravel(): flatten(): 2.矩阵存储与内存结构 3.修改矩阵形状的方法 4.特殊矩阵创建 全零矩阵: 如np.zeros(5) 创建含5个零的一维数组&#xff0c;输出中零后的点&#xff08;如 0.&#xff09;表示浮点数类型。 全一矩阵&#xff1a;如n…

SpringCloud seata全局事务

项目https://github.com/apache/incubator-seata docker拉取启动server $ docker run --name seata-server -p 8091:8091 apache/seata-server:2.1.0 seata注册到nacos <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-…