Leetcode 121 买卖股票的最佳时机

Leetcode 121 买卖股票的最佳时机

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例 1:

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

输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

思考过程

首先想到的是贪心算法,即取左边的最小值,右边的最大值就可以实现股票的最大收益

尝试使用动态规划算法,股票状态有两种,持有和不持有

动态规划

①设定dp[i] [0]表示第i天持有股票所获得的最大收益,dp[i] [1]表示第i天不持有股票所获得的最大收益

②当第i天持有股票时候最大收益来源是前一天就已经持有为dp[i-1] [0],另外就是今天刚买入是-prices[i]

当第i天不持有股票时最大收益来源是前一天已经不持有股票为dp[i-1] [1],另外就是前一天持有但今天卖出了dp[i-1] [0]+prices[i];

综上所述dp[i] [0]=max(dp[i-1] [0],-prices[i]);dp[i] [1]=max(dp[i-1] [1], dp[i-1] [0]+prices[i])

③一开始第0天时候持有是-prices[0],第0天不持有是0

④循环顺序为从第一天到最后一天

代码实现

int maxProfit(vector<int>& prices) {
    int dp[100001][2];
    dp[0][0]=-prices[0];
    dp[0][1]=0;
    int len=prices.size();
    for(int i=1;i<len;++i){
    	dp[i][0]=max(dp[i-1][0],-prices[i]);
    	dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i]);
	}
	
	return dp[len-1][1];
}
### 动态规划代码及分析 #### 代码 ```python from typing import List class Solution: def maxProfit(self, prices: List[int]) -> int: length = len(prices) if length == 0: return 0 dp = [[0, 0] for _ in range(length)] dp[0][0] = -prices[0] for i in range(1, length): dp[i][0] = max(dp[i - 1][0], -prices[i]) dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]) return dp[-1][-1] ``` #### 分析总结 此代码运用动态规划思想解决问题。`dp[i][0]`表示第`i`天持有股票的最大利润,`dp[i][1]`表示第`i`天不持有股票的最大利润。初始化时,第 0 天持有股票的利润为`-prices[0]`,即买入第一天的股票。在后续遍历中,`dp[i][0]`可能是前一天就持有股票,或者当天买入股票,取两者最大值;`dp[i][1]`可能是前一天就不持有股票,或者前一天持有股票当天卖出,同样取两者最大值。最后返回最后一天不持有股票的最大利润,即为结果[^1]。 ### 贪心算法代码及分析 #### 代码 ```java class Solution { public int maxProfit(int[] prices) { // 边界条件检查:如果数组为空或只有一个元素,无法完成交易,返回0 if (prices == null || prices.length <= 1) { return 0; } // 初始化最低价格为第一天的价格 int minPrice = prices[0]; // 初始化最大利润为0(如果无法盈利就返回0) int maxProfit = 0; // 从第二天开始遍历价格数组 for (int i = 1; i < prices.length; i++) { // 情况1:如果当前价格比历史最低价格还低,更新最低价格 if (prices[i] < minPrice) { minPrice = prices[i]; } // 情况2:如果当前价格高于历史最低价格,计算利润并更新最大利润 else { int currentProfit = prices[i] - minPrice; if (currentProfit > maxProfit) { maxProfit = currentProfit; } } } return maxProfit; } } ``` #### 分析总结 贪心算法的核心在于维护一个最低价格`minPrice`和最大利润`maxProfit`。从第二天开始遍历价格数组,若当前价格低于`minPrice`,则更新`minPrice`;若高于`minPrice`,则计算当前利润,若当前利润大于`maxProfit`,则更新`maxProfit`。最终返回`maxProfit`,此算法的时间复杂度为$O(n)$,空间复杂度为$O(1)$,相对动态规划更为简单高效,但贪心算法只能解决一次买卖的情况,对于复杂的交易规则和限制条件,不如动态规划灵活[^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值