数据结构002:买卖股票的最佳时机

原文链接:数据结构002:买卖股票的最佳时机

题目

给定一个数组 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。

解题思路

结合题意,想获取高额回报,肯定是低买高卖,那我们首先想到的是找出数组中的最小值,当天买入,找出最大值,当天卖出,岂不美哉,但是两个字立马把我们拉回现实,如果数组的最大值在最小值前面呢,不就不符合实际情况了吗。那我们该怎么搞?突然想到这道题与我们之前的最大子数组和的内容有些类似,那解题思路是否类似呢?我们套用一下它的思路,找软柿子捏,先从短的数组开始分析(以{a, b, c, d, e}为例),既然要从短的数组分析,为了找出规律,我们将 f ( i ) f(i) f(i)记为第 i i i天卖出股票时的最大利润。那么,我们需要在[0,i-1]的范围内找到最小值 m i n P r i c e [ 0 , i ) minPrice_{[0,i)} minPrice[0,i),则有 f ( i ) = p r i c e s [ i ] − m i n P r i c e f(i) = prices[i]-minPrice f(i)=prices[i]minPrice

  • i=0:题目要求当天买入,只能在未来的日子卖出。因此,无法在 i = 0 i=0 i=0处卖出,因此,最小值 m i n P r i c e [ 0 , 0 ) = 0 minPrice_{[0,0)} =0 minPrice[0,0)=0 f ( 0 ) = 0 f(0)=0 f(0)=0

  • i=1:这种只能 i = 0 i=0 i=0处买入, i = 1 i=1 i=1处卖出。最小值 m i n P r i c e [ 0 , 1 ) = m a x { a } minPrice_{[0,1)} =max\{ a\} minPrice[0,1)=max{a} f ( 1 ) = b − m i n P r i c e f(1)=b-minPrice f(1)=bminPrice

  • i=2:最小值 m i n P r i c e [ 0 , 2 ) = m a x { m i n P r i c e [ 0 , 1 ) , b } minPrice_{[0,2)}=max\{ minPrice_{[0,1)}, b\} minPrice[0,2)=max{minPrice[0,1),b} f ( 2 ) = c − m i n P r i c e f(2)=c-minPrice f(2)=cminPrice

  • i=3:最小值 m i n P r i c e [ 0 , 3 ) = m a x { m i n P r i c e [ 0 , 2 ) , c } minPrice_{[0,3)}=max\{ minPrice_{[0,2)}, c\} minPrice[0,3)=max{minPrice[0,2),c} f ( 3 ) = d − m i n P r i c e f(3)=d-minPrice f(3)=dminPrice

  • i=4:最小值 m i n P r i c e [ 0 , 4 ) = m a x { m i n P r i c e [ 0 , 3 ) , d } minPrice_{[0,4)}=max\{ minPrice_{[0,3)}, d\} minPrice[0,4)=max{minPrice[0,3),d} f ( 4 ) = e − m i n P r i c e f(4)=e-minPrice f(4)=eminPrice

上面我们已经把prices = {a, b, c, d, e}中,第 i i i天卖出股票的所有情况都列举出来了,那么要求一次交易获取的最大利润 m a x P r o f i t maxProfit maxProfit就变得很简单了:
m a x P r o f i t = m a x { f ( 0 ) , f ( 1 ) , f ( 2 ) , f ( 3 ) , f ( 4 ) } maxProfit=max\{f(0), f(1), f(2), f(3), f(4)\} maxProfit=max{f(0),f(1),f(2),f(3),f(4)}
结合上面的分析,该问题的实现代码应该如下:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int minPrice = numeric_limits<int>::max(); //将minPrice初始化为一个int型最大值,同时兼容i=0时的情况
        int maxProfit = 0;
        for (int price: prices) {
            maxProfit = max(maxProfit, price - minPrice);
            minPrice = min(price, minPrice); //对应minPrice[0,i)=max{minPrice[0,1-1), prices[i-1]}
        }
        return maxProfit;
    }
};

上述代码,只进行了一次循环,因此其时间复杂度为 O ( n ) O(n) O(n),空间上,用了常数个变量,空间复杂度为 O ( 1 ) O(1) O(1)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艰默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值