代码随想录算法训练营第四十天 | 股票问题

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

文章链接
题目链接:121.买卖股票的最佳时机

思路

方法1:暴力

看到题目最直接的想法是双层遍历求最大区间差

class Solution:def maxProfit(self, prices):if len(prices) <= 1:return 0result = 0for i in range(len(prices)):for j in range(i + 1, len(prices)):result = max(result, prices[j] - prices[i])return result

这种方法的时间复杂度为O(n^2),会超时

方法2:贪心

一次遍历,向左求最小值,向右求最大值,再用求得的两个值求差。
或者,也可以这样,一次遍历过程中,更新最小值,同时更新 result 为max(prices[i] - 最小值,result)。

class Solution:def maxProfit(self, prices: List[int]) -> int:if len(prices) <= 1:return 0low, result = float('inf'), 0for price in prices:low = min(low, price)   # 向左找最小值result = max(result, price - low)   # 直接取最大区间利益return result
方法3:动态规划

因为需要考虑是否买入股票和卖出股票,所以对应的dp数组为二维数组,分别保存当前持有股票和没持有股票得到的利润(持有可能是之前买入了,不一定是当前买入)
动规五部曲:

  • dp数组及含义:
    dp[i][0]表示当前持有股票的利润,dp[i][1]表示当前没持有股票所获得的利润。
    可以理解最开始现金为0,因此持有股票时,利润为 - prices[j],即股票价格的负数
  • 递推公式:
    dp[i][0]的来源:
    ① 上一天持有股票,dp[i - 1][0]
    ② 上一天不持有股票,今天买入了股票,-prices[i]
    因为是获取的最大利润,所以是求max(也可以理解上面这个过程是在求最低的股票价格)
    dp[i][1]的来源:
    ① 上一天持有股票,今天卖出去了,利润为prices[i] + dp[i - 1][0]([0]是负的)
    ② 上一天不持有股票,利润为dp[i - 1][1]
    也是求max
  • 初始化
    由递推公式可知,dp[i]只与dp[i - 1]有关,因此初始化dp[0],第1天持有股票,只可能是第1天买入,dp[0][0] = -prices[0],第1天不持有股票,利润自然是0,dp[0][1] = 0
  • 遍历顺序
    从前往后
  • 举例
    最后最大利润是dp[len - 1][1],因为dp[0]一定小于0
    在这里插入图片描述
class Solution:def maxProfit(self, prices: List[int]) -> int:if len(prices) <= 1:return 0dp = [[0,0] for _ in range(len(prices))]# 初始化dp[0][0] = -prices[0]dp[0][1] = 0# 遍历for i in range(1, len(prices)):dp[i][0] = max(dp[i - 1][0], -prices[i])dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0])return dp[-1][1]

仔细研究递推式会发现,dp[i]只与dp[i - 1]有关,因此dp数组可以缩小为2*2的数组

class Solution:def maxProfit(self, prices: List[int]) -> int:if len(prices) <= 1:return 0len_prices = len(prices)dp = [[0, 0], [0, 0]]# 初始化dp[0][0] = -prices[0]dp[0][1] = 0# 遍历for i in range(1, len_prices):dp[i % 2][0] = max(dp[(i - 1) % 2][0], -prices[i])dp[i % 2][1] = max(dp[(i - 1) % 2][1], prices[i] + dp[(i - 1) % 2][0])return dp[(len_prices - 1) % 2][1]

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

文章链接
题目链接:122.买卖股票的最佳时机Ⅱ

思路

方法1:贪心

之前用过,基本思路是:昨天买入,今天卖出。如果亏了,就当作昨天没买入,不算入利润;赚了就算入利润。然后除最后一天外都会买入

class Solution:def maxProfit(self, prices: List[int]) -> int:if len(prices) <= 1:return 0maxprofit = 0preprice = prices[0]for price in prices[1:]:maxprofit += max(0, price - preprice)preprice = pricereturn maxprofit
方法2:动态规划:

首先弄清楚本题与上题的区别,上题是股票只有一次买入和卖出的机会,这次是股票可以经历多次买入和卖出。
动规五部曲中,dp数组及含义是相同的,递推式有不同,因为可以多次买入和卖出,因此dp[i][0]
① 昨天持有股票:dp[i - 1][0]
② 昨天没持有股票:之前的题目,如果昨天没持有股票,那么认为之前利润为0,更新的利润为 - prices[i];而这道题,昨天没有持有股票可能是昨天卖出去,已经有了一部分利润,因此为 dp[i - 1][1] - prices[i] (且上道题的递推式不能用这道题的
其余相同
举例
到最后获得最大利润一定是手上没有股票了
在这里插入图片描述

"""
也可以像上一题一样把dp变成2*2的数组,因为递推式dp[i]还是只与dp[i - 1]有关
"""
class Solution:def maxProfit(self, prices: List[int]) -> int:if len(prices) <= 1:return 0len_prices = len(prices)dp = [[0, 0] for _ in range(len_prices)]# 初始化dp[0][0] = -prices[0]   # 持有股票的利润# 遍历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])  # 不持有股票return dp[len_prices - 1][1]

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

文章链接
题目链接:123.买卖股票的最佳时机Ⅲ

思路:

首先分析题目,题目要求最多可以完成两笔交易,因此在原来分是否持有的基础上,需要继续分为是第一次还是第二次。
动规五部曲:

  • dp数组及含义:
    dp[i]应当有4列,dp[i][0]为第一次持有,dp[i][1]为第一次不持有,dp[i][2]为第二次持有,dp[i][3]为第二次不持有。后面接的都是最大利润。
    注意:持有不是当天买入,之前买入,现在不卖出也是持有
  • 递推公式:
    • dp[i][0]:
      第一次持有,如果昨天持有:dp[i - 1][0];如果昨天没持有,今天买入:-prices[i](因为是第一次,所以前面没有利润)
    • dp[i][1]:
      昨天持有,今天卖出:dp[i - 1][0] + prices[i]
      昨天没持有:dp[i - 1][1]
    • dp[i][2]:
      昨天持有:dp[i - 1][2]
      昨天没持有,今天买入(第二次,之前有利润):dp[i - 1][1] - prices[i]
    • dp[i]][3]:
      昨天持有,今天卖出:dp[i - 1][2] + prices[i]
      昨天没持有:dp[i - 1][3]
      并且都是求最大值
  • 初始化:
    由递推公式可知,应当初始化dp[0],因为是第一天,只要是买入,不管第几次买入,都是-prices[0],只要是卖出,肯定是当天买入当天卖出,都是0
  • 遍历方式:
    从前往后
  • 举例
    最后求的最大利润一定是dp[-1][3]的值,判断原因如下:
    ① 如果是一次买入卖出就得到了最大值,那第二次买入卖出肯定是都是当天,因此dp[-1][1] 等于dp[-1][3]
    ② 如果是两次买入卖出得到最大值,那也就是dp[-1][3]的值
    在这里插入图片描述
class Solution:def maxProfit(self, prices: List[int]) -> int:if len(prices) <= 1:return 0# 初始化len_prices = len(prices)dp = [[0,0,0,0] for _ in range(len_prices)]dp[0][0] = dp[0][2] = -prices[0]# 遍历for i in range(1, 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])  # 第一次卖出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])  # 第二次卖出return dp[len_prices - 1][3]

学习收获:

买卖股票最佳时机,重要要分析题目得到 dp[i] 有多少种状态,以及只能一次买入卖出、多次买入卖出和限定买入卖出的最大次数的递推公式(或者可以说是一次买入卖出和多次买入卖出公式的结合,区别在于买入的利润是否要加上上一次买卖股票的利润)

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

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

相关文章

EyeSoothe: Your Ultimate Eye Health Companion

In today’s screen-dominated world, our eyes deserve extra care. EyeSoothe is the ultimate app for anyone looking to track their vision, rejuvenate tired eyes, and find the perfect eyewear—all powered by intelligent AI and packed into one seamless app. h…

AnaConda下载PyTorch慢的解决办法

使用Conda下载比较慢&#xff0c;改为pip下载 复制下载链接到迅雷下载 激活虚拟环境&#xff0c;安装whl&#xff0c;即可安装成功 pip install D:\openai.wiki\ChatGLM2-6B\torch-2.4.1cu121-cp38-cp38-win_amd64.whl

【python】matplotlib(radar chart)

文章目录 1、功能描述和原理介绍2、代码实现3、效果展示4、完整代码5、多个雷达图绘制在一张图上6、参考 1、功能描述和原理介绍 基于 matplotlib 实现雷达图的绘制 一、雷达图的基本概念 雷达图&#xff08;Radar Chart&#xff09;&#xff0c;也被称为蛛网图或星型图&…

鸿蒙APP之从开发到发布的一点心得

引言&#xff1a; 做鸿蒙开发大概有1年左右时间了&#xff0c;从最开始的看官方文档、看B站视频&#xff0c;到后来成功发布两款个人APP&#xff08;房贷计算极简版、时简时钟 轻喷&#xff0c;谢谢&#xff09;。简单描述一下里边遇到的坑以及一些经历吧。 学习鸿蒙开发 个…

Clisoft SOS与CAD系统集成

Clisoft SOS与CAD系统集成 以下内容大部分来自官方文档&#xff0c;目前只用到与Cadence Virtuoso集成&#xff0c;其他还未用到&#xff0c;如有问题或相关建议&#xff0c;可以留言。 与Keysight ADS集成 更新SOS客户端配置文件sos.cfg&#xff0c;以包含支持ADS的模板&am…

IP查询于访问控制保护你我安全

IP地址查询 查询方法&#xff1a; 命令行工具&#xff1a; ①在Windows系统中&#xff0c;我们可以使用命令提示符&#xff08;WINR&#xff09;查询IP地址&#xff0c;在弹窗中输入“ipconfig”命令查看本地网络适配器的IP地址等配置信息&#xff1b; ②在Linux系统中&…

人工智能训练师一级(高级技师)、二级(技师)考试指南

随着经济快速发展&#xff0c;人工智能技术在制造业、交通运输、农业、医疗健康、金融服务、物流配送以及城市服务等多个领域得到了广泛的应用。不仅带来产业的转型升级&#xff0c;更是对具备相应技能的人工智能训练师需求的激增。 根据教育部发布的《关于做好职业教育“…

ArmSoM RK3588/RK3576核心板,开发板网络设置

ArmSoM系列产品都搭配了以太网口或WIFI模块&#xff0c;PCIE转以太网模块、 USB转以太网模块等&#xff0c;这样我们的网络需求就不止是上网这么简单了&#xff0c;可以衍生出多种不同的玩法。 1. 网络连接​ 连接互联网或者组成局域网都需要满足一个前提–设备需要获取到ip&a…

patchwork++地面分割学习笔记

参考资料&#xff1a;古月居 - ROS机器人知识分享社区 https://zhuanlan.zhihu.com/p/644297447 patchwork算法一共包含四部分内容&#xff1a;提出了以下四个部分&#xff1a;RNR、RVPF、A-GLE 和 TGR。 1&#xff09;基于 3D LiDAR 反射模型的反射噪声消除 (RNR)&#xff…

关于Mac中的shell

1 MacOS中的shell 介绍&#xff1a; 在 macOS 系统中&#xff0c;Shell 是命令行与系统交互的工具&#xff0c;用于执行命令、运行脚本和管理系统。macOS 提供了多种 Shell&#xff0c;主要包括 bash 和 zsh。在 macOS Catalina&#xff08;10.15&#xff09;之前&#xff0c…

IO: 作业:Day1

思维导图 main.c #include"student.h" int main(int argc, const char *argv[]) { stuPtr hcreat(); int n0; add_node(h); add_node(h); add_node(h); show(h); save(h,"student.txt"); stuPtr ptrc…

java 转义 反斜杠 Unexpected internal error near index 1

代码&#xff1a; String str"a\\c"; //出现异常&#xff0c;Unexpected internal error near index 1 //System.out.println(str.replaceAll("\\", "c"));//以下三种都正确 System.out.println(str.replace(\\, c)); System.out.println(str.r…

以C++为基础快速了解C#

using System: - using 关键字用于在程序中包含 System 命名空间。 一个程序一般有多个 using 语句, 相当于C的 using namespace std; C# 是大小写敏感的。 所有的语句和表达式必须以分号&#xff08;;&#xff09;结尾。 程序的执行从 Main 方法开始。 与 Java 不同的是&#…

面向对象的思维hong

首尾相连和转多段线

Mysql--基础篇--数据类型(整数,浮点数,日期,枚举,二进制,空间类型等)

MySQL提供了多种数据类型&#xff0c;用于定义表中列的数据格式。选择合适的数据类型不仅可以提高查询性能&#xff0c;还能确保数据的完整性和准确性。 一、数值类型 数值类型用于存储整数、浮点数和定点数。根据精度和范围的不同&#xff0c;数值类型可以分为以下几类&…

nlp培训重点-2

1. 贝叶斯公式 import math import jieba import re import os import json from collections import defaultdictjieba.initialize()""" 贝叶斯分类实践P(A|B) (P(A) * P(B|A)) / P(B) 事件A&#xff1a;文本属于类别x1。文本属于类别x的概率&#xff0c;记做…

sunrays-framework(太阳射线框架搭建)

文章目录 1.基本环境搭建1.创建项目sunrays-framework2.新增忽略文件3.删除src目录4.交给Git管理 2.sunrays-dependencies模块&#xff1a;统一管理依赖1.创建模块2.不要交给父模块管理&#xff0c;这是独立的&#xff01;&#xff01;&#xff01;3.删除src目录4.pom.xml统一管…

JVM vs JDK vs JRE

JVM是Java虚拟机的缩写&#xff0c; 用于实现Java的一次编译&#xff0c;处处运行。 Java代码写成.class后&#xff0c;由本地的虚拟机运行。 JDK&#xff08;Java Development Kit&#xff09;是一个功能齐全的 Java 开发工具包&#xff0c;供开发者使用。 JDK包含了JRE。…

Android修改开机动画路径

frameworks\base\cmds\bootanimation\BootAnimation.cpp 路径的定义 优先查找的顺序

select下拉框,首次进入页面没有显示value的情况

bug场景&#xff1a; 类似这种bug情况排查如下&#xff1a; 首先 理解含义 options就是存放键值对的&#xff0c;id就是key&#xff0c;对上了它就自动把label显示 而且如果你用来当作key和label的字段&#xff0c;与后端返回的不一致&#xff0c;还可以进行更改 其次 排查接…