【leetcode】40-best-time-to-buy-and-sell-stock 力扣 121. 买卖股票的最佳时机

买卖股票系列

【leetcode】40-best-time-to-buy-and-sell-stock 力扣 121. 买卖股票的最佳时机

【leetcode】41-best-time-to-buy-and-sell-stock-ii 力扣 122. 买卖股票的最佳时机 II

【leetcode】42-best-time-to-buy-and-sell-stock-iii 力扣 123. 买卖股票的最佳时机 III

【leetcode】43-best-time-to-buy-and-sell-stock-iv 力扣 188. 买卖股票的最佳时机 IV

【leetcode】44-best-time-to-buy-and-sell-stock-with-cooldown 力扣 309. 买卖股票的最佳时机包含冷冻期

【leetcode】45-best-time-to-buy-and-sell-stock-with-cooldown 力扣 714. 买卖股票的最佳时机包含手续费

开源地址

为了便于大家学习,所有实现均已开源。欢迎 fork + star~

https://github.com/houbb/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。

提示:

1 <= prices.length <= 10^5
0 <= prices[i] <= 10^4

V1-暴力解法

 /**
 * 最简单的暴力算法
 * @param prices 价格
 * @return 结果
 */
 public int maxProfit(int[] prices) {
 int maxResult = 0;
 for(int i = 0; i < prices.length-1; i++) {
 for(int j = i+1; j < prices.length; j++) {
 int profit = prices[j] - prices[i];
 maxResult = Math.max(profit, maxResult);
 }
 }
 return maxResult;
 }

这种解法会超时。

v2-如何优化呢?

核心的一点:最大的利润,卖出之前则必须是买入的最小值、卖出的最大值。

所以只需要做几件事:

0)最大值,最小值初始化为 prices[0];

1)记录最大的利润 maxResult = maxPrice - minPrice;

2)如果遇到了最小值,则重新初始化 minPrice, maxPrice

代码实现

 public int maxProfit(int[] prices) {
 int maxResult = 0;
 int minVal = prices[0];
 int maxVal = prices[0];
 for(int i = 1; i < prices.length; i++) {
 int cur = prices[i];
 // 值大于当前值
 if(cur > maxVal) {
 maxResult = Math.max(maxResult, cur - minVal);
 }
 // 重置
 if(cur < minVal) {
 minVal = cur;
 maxVal = cur;
 }
 }
 return maxResult;
 }

V2.5-代码性能优化

优化思路

上面的分支判断太多

核心实现

class Solution {
 public int maxProfit(int[] prices) {
 int maxResult = 0;
 int minVal = prices[0];
 for(int i = 0; i < prices.length; i++) {
 minVal = Math.min(minVal, prices[i]);
 maxResult = Math.max(prices[i] - minVal, maxResult);
 }
 return maxResult;
 }
 
}

效果

1ms 击败100.00%

V3-DP 的思路-贯穿整体解法

思路

我们一共完成了一笔完整的交易,分为两步:

  1. b1 买入1
  2. s1 卖出1

卖出+买入构成了完整的交易。

每一天我们都可以决定是否买,是否卖?

初始化

b1 买入时,我们初始化为 -prices[0];

s1 卖出时,初始化为0;

代码

public int maxProfit(int[] prices) {
 int b1 = -prices[0];
 int s1 = 0;
 for(int i = 0; i < prices.length; i++) {
 // 卖出第一笔 是否卖? 不卖则为s1, 卖出则为 b1 + prices[i]
 s1 = Math.max(s1, b1 + prices[i]);
 // 买入第一笔 是否买? 如果买,则花费为当前金额;
 b1 = Math.max(b1, - prices[i]);
 }
 return s1;
}
作者:老马啸西风原文地址:https://www.cnblogs.com/houbbBlogs/p/18531219

%s 个评论

要回复文章请先登录注册