day 49 :121. 买卖股票的最佳时机;122. 买卖股票的最佳时机 II;123. 买卖股票的最佳时机 III

news/2025/2/16 0:19:51/

买卖股票

  • 121. 买卖股票的最佳时机:一次买入卖出
    • 1. 贪心算法
    • 2. 动态规划
      • 1. dp数组以及下标名义
      • 2. 递归公式
      • 3. dp数组如何初始化
      • 4. 代码
  • 122. 买卖股票的最佳时机 II:可以多次买入卖出
    • 2. 动态规划
      • 1. dp数组以及下标名义
      • 2. 递归公式
      • 3. dp数组如何初始化
      • 4. 代码
  • 123. 买卖股票的最佳时机 III:最多完成两笔交易
    • 2. 动态规划
      • 1. dp数组以及下标名义
      • 2. 递归公式
      • 3. dp数组如何初始化
      • 4. 代码
  • 188. 买卖股票的最佳时机 IV:k次买入,k次卖出
    • 2. 动态规划
      • 1. dp数组以及下标名义
    • 2. 递归公式
      • 3. dp数组如何初始化
      • 4. 代码

121. 买卖股票的最佳时机:一次买入卖出

在这里插入图片描述

1. 贪心算法

找最左边的最小值,和最右边的最大值,相减

class Solution {
public://贪心int maxProfit(vector<int>& prices) {int leftmin = INT_MAX;int result = 0;for(int i = 0; i < prices.size(); i++) {leftmin = min(leftmin, prices[i]);result = max(result, prices[i] - leftmin);}      return result;}
};

2. 动态规划

1. dp数组以及下标名义

dp[i][0] : 第i天,持有股票的最大收益, 可能之前买了不一定i天买

dp[i][1] : 第i天,不持有股票的最大收益,可能之前卖了不一定i天卖

2. 递归公式

如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来

  1. 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]

  2. 第i天买入股票,所得现金就是买入今天的股票后所得现金即:-prices[i],现金本身为0,股票只买卖一次

  3. 所以:dp[i][0] = max(dp[i - 1][0],-prices[i])
    如果第i天不持有股票即dp[i][1], 那么可以由两个状态推出来

  4. 第i-1天就不持有股票,那么就保持现状, 即:dp[i - 1][1]

  5. 第i天卖出股票,所得现金就是卖出今天的股票后所得现金即:dp[i - 1][0] + prices[i]

  6. 所以:dp[i][0] = max(dp[i - 1][0] + prices[i], dp[i - 1][1])

3. dp数组如何初始化

dp[0][0] = -p[0];
dp[0][1] = 0;

4. 代码

class Solution {
public://贪心int maxProfit(vector<int>& prices) {vector<vector<int>>dp(prices.size() + 1, vector<int>(2 , 0));dp[0][0] = - prices[0];for(int i = 1; i < prices.size(); i++) {dp[i][0] = max(dp[i - 1][0], - prices[i]); //第i天持有股票即dp[i][0]= 第i-1天就持有股票 or 第i天买入股票dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);//第i天不持有股票即dp[i][1] =第i-1天就不持有股票or第i天卖出股票}return max(dp[prices.size() - 1][0], dp[prices.size() - 1][1]);}
};

122. 买卖股票的最佳时机 II:可以多次买入卖出

在这里插入图片描述

2. 动态规划

1. dp数组以及下标名义

dp[i][0] : 第i天,持有股票的最大收益, 可能之前买了不一定i天买

dp[i][1] : 第i天,不持有股票的最大收益,可能之前卖了不一定i天卖

2. 递归公式

如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来

  1. 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]

  2. 第i天买入股票,所得现金就是买入今天的股票后所得现金即:-prices[i],现金本身为0,股票只买卖一次

  3. 所以:dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] -prices[i])和上一题不一样的地方
    如果第i天不持有股票即dp[i][1], 那么可以由两个状态推出来

  4. 第i-1天就不持有股票,那么就保持现状, 即:dp[i - 1][1]

  5. 第i天卖出股票,所得现金就是卖出今天的股票后所得现金即:dp[i - 1][0] + prices[i]

  6. 所以:dp[i][0] = max(dp[i - 1][0] + prices[i], dp[i - 1][1])

3. dp数组如何初始化

dp[0][0] = -p[0];
dp[0][1] = 0;

4. 代码

class Solution {
public://贪心int maxProfit(vector<int>& prices) {vector<vector<int>>dp(prices.size() + 1, vector<int>(2 , 0));dp[0][0] = - prices[0];for(int i = 1; i < prices.size(); i++) {dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]- prices[i]); //第i天持有股票即dp[i][0]= 第i-1天就持有股票 or 第i天买入股票dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);//第i天不持有股票即dp[i][1] =第i-1天就不持有股票or第i天卖出股票}return max(dp[prices.size() - 1][0], dp[prices.size() - 1][1]);}
};

123. 买卖股票的最佳时机 III:最多完成两笔交易

2. 动态规划

1. dp数组以及下标名义

一天一共就有五个状态,

0:没有操作 (其实我们也可以不设置这个状态)
1:第一次持有股票
2:第一次不持有股票
3:第二次持有股票
4:第二次不持有股票

2. 递归公式

情况一. dp[i][1]:

如果第i天第一次持有股票即dp[i][1], 不是说第i天一定要买入股票,可能之前就买入了股票

  1. 操作一:第i-1天没有操作:第一次持有股票:dp[i - 1][1]
  2. 操作二:第i天买入股票,则第i-1天不持有股票:- prices[i]
  3. 所以:dp[i][1] = max(dp[i - 1][1], - prices[i])

情况二. dp[i][2]:

  1. 操作一:第i天没有操作:延续前一天:dp[i - 1][2]
  2. 操作二:第i天卖出股票,则:dp[i - 1][1] + prices[i]
  3. dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2])

情况三. dp[i][3]:

  1. 操作一:第i天没有操作:dp[i - 1][3]
  2. 操作二:第i天买入股票,则:dp[i - 1][2] - prices[i]
  3. dp[i][3] = max(dp[i - 1][2] - prices[i], dp[i - 1][3])

情况四. dp[i][4]:

  1. 操作一:第i天没有操作:延续前一天:dp[i - 1][4]
  2. 操作二:第i天卖出股票,则:dp[i - 1][3] + prices[i]
  3. dp[i][4] = max(dp[i - 1][3] + prices[i], dp[i - 1][4])

3. dp数组如何初始化

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

4. 代码

class Solution {
public:int maxProfit(vector<int>& prices) {vector<vector<int>>dp(prices.size() + 1, 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], - prices[i]);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][3] + prices[i], dp[i - 1][4]);}int high1 = max(dp[prices.size() - 1][1], dp[prices.size() - 1][2]);int high2 = max(dp[prices.size() - 1][3], dp[prices.size() - 1][4]);return max(high1,high2);}
};

188. 买卖股票的最佳时机 IV:k次买入,k次卖出

2. 动态规划

1. dp数组以及下标名义

使用二维数组 dp[i][j] :第i天的状态为j,所剩下的最大现金是dp[i][j]
j的状态表示为:

0 表示不操作
1 第一次买入
2 第一次卖出
3 第二次买入
4 第二次卖出

2. 递归公式

情况一. dp[i][1]:

如果第i天第一次持有股票即dp[i][1], 不是说第i天一定要买入股票,可能之前就买入了股票

  1. 操作一:第i-1天没有操作:第一次持有股票:dp[i - 1][1]
  2. 操作二:第i天买入股票,则第i-1天不持有股票:- prices[i]
  3. 所以:dp[i][1] = max( - prices[i],dp[i - 1][1])

情况二. dp[i][2]:

  1. 操作一:第i天没有操作:延续前一天:dp[i - 1][2]
  2. 操作二:第i天卖出股票,则:dp[i - 1][1] + prices[i]
  3. dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2])

情况三. dp[i][3]:

  1. 操作一:第i天没有操作:dp[i - 1][3]
  2. 操作二:第i天买入股票,则:dp[i - 1][2] - prices[i]
  3. dp[i][3] = max(dp[i - 1][2] - prices[i], dp[i - 1][3])
  for(int i = 1; i < prices.size(); i++) {for(int j = 0; j < 2 * k - 1; j = j + 2) { //k = 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]);}

3. dp数组如何初始化

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

4. 代码

class Solution {
public:int maxProfit(int k, vector<int>& prices) {vector<vector<int>>dp(prices.size() + 1, vector<int>(2 * k + 1, 0));for(int i = 1; i < 2 * k; i = i + 2) {dp[0][i] = - prices[0];}for(int i = 1; i < prices.size(); i++) {for(int j = 0; j < 2 * k - 1; j = j + 2) { //k = 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];}
};

http://www.ppmy.cn/news/246364.html

相关文章

Web3.0概念

学习web3您需要先掌握 JavaScript node React 后续 我们将学习一门新的语言 叫 Solidity 他是一种只能合约语言开发 我们利用web3将不再依赖后端 而是连接只能合约开发 首先 我们先不用急着写代码 还是要概念为先 首先 我们来对比 WEB1.0到3.0的概念 首先 web1.0 更多处于信…

unity 开发中10个小知识(一)

现在记忆力越来越差&#xff0c;写过很多遍的内容&#xff0c;都有可能需要慢慢才能想起来&#xff0c;这里就记录下在unity开发过程中一些小的知识点 一、获取unity层级和layerMask int ground LayerMask.NameToLayer("Ground"); int groundMask 1<<ground…

Qt/GUI/布局/实现窗口折叠效果/且在操作时父窗口尺寸跟随变动

文章目录 概述无法resize到小尺寸可行方案其他方案 概述 本文旨在&#xff0c;实现如下所示的显示或隐藏 ‘附加选项’ 的效果&#xff0c;以折的不常用信息和操作项&#xff0c;减少普通用户负担&#xff0c;提升用户体验。在某些软件中此类窗口折叠效果&#xff0c;常用 “……

地图实火!断货加印,限时折扣抢购通道开启

&#xff08;关注公众号点击图片三折购买《社交泛娱乐出海作战地图》&#xff09; 实火&#xff01; 融云自制《社交泛娱乐出海作战地图》 “WICC 泛娱乐出海嘉年华”最热单品 关注【融云全球互联网通信云】了解更多 《出海作战地图》线下首发立刻引爆现场&#xff0c;“如…

springboot源码分析-jar启动

概述 Spring Boot 提供了 Maven 插件 spring-boot-maven-plugin&#xff0c;可以方便的将 Spring Boot 项目打成 jar 包或者 war 包。 SpringBoot 是如何通过jar包启动的 java -jar做了什么&#xff1f;看看官网怎么说 If the -jar option is specified, its argument is the …

通达信l1l2行情接口是什么?

通达信l1l2行情接口是什么&#xff1f;L1L2是指L1L2范数&#xff0c;范数理解为”空间两点之间的距离“这个概念被扩展了。 权重w可以理解为高维向量&#xff0c;也可以理解为高维空间中的一个点。如果从这个点到原点的距离是欧洲距离&#xff0c;那就是L2范数&#xff0c;如图…

如何调用通达信l2行情接口?

如何调用通达信l2行情接口&#xff1f;今天小编&#xff0c;就用这三个场景说明一下&#xff0c;如下&#xff1a; 1、API平台生成公钥&#xff0c;发布公钥并提供给需要连接API的人员。 2、Tradex涵盖市场接收、访问、管理和定制&#xff0c;实现一揽子解决方式。 3、量化接…

东方财富、同花顺、大智慧、通达信的Level2行情接口哪个好?

其实Level2行情接口最主要的核心是逐笔委托和逐笔成交的买卖单数据&#xff0c;盘口数据转瞬即逝&#xff0c;如何能方便的在程序中调用到最全面的即时数据才是应该关心的内容。至于看盘&#xff0c;再好的眼神再快的人脑也比不过使用软件程序写出自己的交易方法让电脑的精准和…