股票问题

news/2024/9/17 4:04:58

121题

给定一个数组prices,其中prices[i]是一支给定股票第i天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。但是,你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例

  • 输入:prices = [7,1,5,3,6,4]
  • 输出:5
  • 解释:在第2天(股票价格=1)的时候买入,在第5天(股票价格=6)的时候卖出,最大利润=6-1=5。注意利润不能是7-1=6,因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

解题思路

贪心法:设置一个买入的价格,每次遇到比买入价格大,就换掉。并且每次都要更新最大收益

    public int maxProfit(int[] prices) {int max=0;int buy=prices[0];for (int i = 1; i < prices.length; i++) {max=Math.max(max,prices[i]-buy);if (prices[i]<buy){buy=prices[i];}}return max;}

其他的股票问题均可以使用动态规划解答
动态规划主要是解决两个问题:枚举状态和选择
股票问题的状态:
天数:i
允许交易的最大次数:k
用户账户当前状态(持有或者未持有股票):0,1

dp[i][k][0 or 1] //前面说了三个维度,自然dp数组也是三维的。dp表示利润
for(int i = 0;i < n;i++)
for(int j = 0;j < k;j++)
dp[i][j][0] 取优
dp[i][j][1] 取优//账户状态这个维度只有两种可能,就直接计算就好啦。

122题(k无限制)

给定一个数组prices,其中prices[i]表示某支股票第i天的价格。在每一天,你可以决定是否购买和/或出售股票。你在任何时候最多只能持有一股股票。你也可以先购买,然后在同一天出售。返回你能获得的最大利润。

示例

  • 输入:prices = [7,1,5,3,6,4]
    输出:7
    解释:在第2天(股票价格=1)的时候买入,在第3天(股票价格=5)的时候卖出,这笔交易所能获得利润=5-1=4。随后,在第4天(股票价格=3)的时候买入,在第5天(股票价格=6)的时候卖出,这笔交易所能获得利润=6-3=3。总利润为4+3=7。
  • 输入:prices = [1,2,3,4,5]
    输出:4
    解释:在第1天(股票价格=1)的时候买入,在第5天(股票价格=5)的时候卖出,这笔交易所能获得利润=5-1=4。总利润为4。
  • 输入:prices = [7,6,4,3,1]
    输出:0
    解释:在这种情况下,交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为0。

解题思路

在这个问题中,我们使用动态规划来寻找最优解。我们定义一个二维数组dp,其中dp[i][0]表示第i天交易完后手里没有股票的最大利润,而dp[i][1]表示第i天交易完后手里持有一支股票的最大利润。

根据题目描述,我们可以得到状态转移方程如下:

  1. 如果第i天没有股票(dp[i][0]),那么有两种情况:

    • i-1天也没有股票,并且今天没有进行任何操作(即不买入也不卖出),所以dp[i][0] = dp[i-1][0]
    • i-1天持有股票,但今天卖出了股票,所以dp[i][0] = dp[i-1][1] + prices[i](其中prices[i]是第i天的股票价格)。

    取这两种情况中的较大值,即:dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i])

  2. 如果第i天持有股票(dp[i][1]),那么也有两种情况:

    • i-1天也持有股票,并且今天没有进行任何操作(即不卖出也不买入),所以dp[i][1] = dp[i-1][1]
    • i-1天没有股票,但今天买入了股票,所以dp[i][1] = dp[i-1][0] - prices[i]

    取这两种情况中的较大值,即:dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i])

注意,初始化时,dp[0][0]应该是0(因为没有股票且没有进行任何交易),而dp[0][1]应该是-prices[0](因为我们在第一天买入了一支股票)。

最后,答案就是dp[n-1][0],其中n是股票价格的长度,表示最后一天交易完后手里没有股票的最大利润。

class Solution {public int maxProfit(int[] prices) {int[][] dp = new int[prices.length][2];//0为未持有,1为持有dp[0][0] = 0;dp[0][1] = 0 - prices[0];for(int i = 1;i < prices.length;i++){dp[i][0] = Math.max(dp[i - 1][0],dp[i - 1][1] + prices[i]);dp[i][1] = Math.max(dp[i - 1][1],dp[i - 1][0] - prices[i]);}return dp[prices.length - 1][0];}
}

714题(有费用)

买卖股票的最佳时机含手续费

给定一个整数数组 prices,其中第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

此外,你还需要支付交易费用,每次交易(买入或卖出)都需要支付一个固定的费用 fee

返回你可以从这笔交易中获取的最大利润。

示例 1:

输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
输出: 8
解释: 能够达到的最大利润:
在此处买入 prices[0] = 1
在此处卖出 prices[3] = 8
在此处买入 prices[4] = 4
在此处卖出 prices[5] = 9
总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8

解题思路

如果第i天不持有股票(dp[i][0]):
第i-1天也不持有股票,今天没有进行任何操作:dp[i][0] = dp[i-1][0]
第i-1天持有股票,今天卖出了股票,需要支付手续费:dp[i][0] = dp[i-1][1] + prices[i] - fee
取这两者中的较大值:
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i] - fee);
如果第i天持有股票(dp[i][1]):
第i-1天就持有股票,今天没有进行任何操作:dp[i][1] = dp[i-1][1]
第i-1天不持有股票,但今天买入了股票(注意:这里不直接考虑手续费,因为手续费是在卖出时支付的):dp[i][1] = dp[i-1][0] - prices[i]
取这两者中的较大值:
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);

class Solution {public int maxProfit(int[] prices, int fee) {int[][] dp = new int[prices.length][2];//0为未持有,1为持有dp[0][0] = 0;dp[0][1] = 0 - prices[0];for(int i = 1;i < prices.length;i++){dp[i][0] = Math.max(dp[i - 1][0],dp[i - 1][1] + prices[i] - fee);dp[i][1] = Math.max(dp[i - 1][1],dp[i - 1][0] - prices[i]);}return dp[prices.length - 1][0];}
}

309

题目描述

给定一个整数数组prices,其中第i个元素是一支给定股票第i天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

  1. 交易限制:你不能同时参与多笔交易(即你必须在再次购买前出售掉之前的股票)。
  2. 冷冻期:卖出股票后,你无法在第二天买入股票(即冷冻期为1天)。

示例

输入: [1,2,3,0,2]
输出: 3
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]

解题思路

通过定义一个二维数组 dp 来存储不同状态下的最大利润。

变量定义

  1. int n = prices.length;:获取输入股票价格数组的长度。
  2. int[][] dp = new int[n][3];:定义一个二维数组 dp,其中 dp[i][0] 表示第 i 天不持有股票的最大利润,dp[i][1] 表示第 i 天持有股票的最大利润,dp[i][2] 表示第 i 天处于冷冻期的最大利润。

初始化

  1. dp[0][0] = 0;:第一天不持有股票时利润为 0,因为还没有进行任何买卖操作。
  2. dp[0][1] = -prices[0];:第一天持有股票,意味着花费了 prices[0] 的成本,所以利润为 -prices[0]
  3. dp[0][2] = 0;:第一天不可能处于冷冻期,所以利润为 0。

状态转移方程

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

    • i 天不持有股票有两种情况:
      • i - 1 天就不持有股票,利润为 dp[i - 1][0]
      • i - 1 天持有股票,第 i 天卖出,利润为 dp[i - 1][1] + prices[i](卖出价格为 prices[i])。
    • 取这两种情况的较大值作为第 i 天不持有股票的最大利润。
  2. dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][2] - prices[i]);

    • i 天持有股票有两种情况:
      • i - 1 天就持有股票,利润为 dp[i - 1][1]
      • i - 1 天处于冷冻期,第 i 天买入股票,利润为 dp[i - 1][2] - prices[i](买入价格为 prices[i])。
    • 取这两种情况的较大值作为第 i 天持有股票的最大利润。
  3. dp[i][2] = dp[i - 1][0];

    • i 天处于冷冻期,说明第 i - 1 天卖出了股票,所以第 i 天的冷冻期利润等于第 i - 1 天不持有股票的利润,即 dp[i - 1][0]

最终结果

返回 Math.max(dp[n - 1][0], dp[n - 1][2]),因为最后一天的最大利润可能是不持有股票(dp[n - 1][0])或者处于冷冻期(dp[n - 1][2])的情况,取两者中的较大值作为最终的最大利润。

class Solution {public int maxProfit(int[] prices) {if (prices == null || prices.length <= 1) {return 0;}int n = prices.length;// dp[i][0] 表示第 i 天不持有股票的最大利润// dp[i][1] 表示第 i 天持有股票的最大利润// dp[i][2] 表示第 i 天处于冷冻期的最大利润int[][] dp = new int[n][3];dp[0][0] = 0;dp[0][1] = -prices[0];dp[0][2] = 0;for (int i = 1; i < n; i++) {dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][2] - prices[i]);dp[i][2] = dp[i - 1][0];}return Math.max(dp[n - 1][0], dp[n - 1][2]);}
}

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

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

相关文章

VsCode+WSL2+Python3+git机器学习环境安装

安装VsCode,添加WSL扩展插件用管理员权限打开PowerShellwsl --install此命令将启用运行 WSL 并安装 Linux 的 Ubuntu 发行版所需的功能 wsl --set-version <distro name> 2命令将 替换为要更新的 Linux 发行版的名称,如wsl --set-version Ubuntu 2 会将 Ubuntu设置为使…

English Level A, B, C All In One

English Level A, B, C All In One 英语等级 A、B、CEnglish Level A, B, C All In One英语等级 A、B、CEnglish level A1 A2 B1 B2 C1 C2 The CEFR and EF SETB1 LevelB1 Intermediate / 中级 EF SET 41-50https://www.efset.org/cefr/b1/B2 LevelB2 Upper intermediate / 中上…

自动化运维工具之WGCLOUD使用操作指南,为服务器安全保驾护航

WGCLOUD官网下载安装包:www.wgstart.com 1、部署WGCLOUD运行的前置条件说明WGCLOUD包括:server为服务端(或主控端),agent为客户端(探针端、被控端)WGCLOUD的server和agent,可以部署在已有业务运行的主机,不要求主机是纯净的操作系统。当然了,纯净的系统也可以部署WG…

C# kvaser can 通讯

1、查看官方文档https://kvaser.com/canlib-webhelp/section_install_windows.html 2、安装can windows驱动 https://www.kvaser.com/downloads-kvaser/?utm_source=software&utm_ean=7330130980013&utm_status=latest 3、安装canlib https://www.kvaser.com/downloa…

Cursor一键导入vscode插件以及设置

在cursor中找到 setting-- general -- vscode import 导入配置,一键导入即可

时间序列结构变化分析:Python实现时间序列变化点检测

平稳性是时间序列分析与预测的核心概念。在平稳条件下,时间序列的统计特性(如均值)在时间维度上保持不变,仅存在随机波动。 但是实际数据集中很少观察到完全的平稳性。时间序列通常会经历结构性断裂或变化。这些变化会引入非平稳性,从而改变时间序列的整体分布,这些标志着…