【算法实例】股票收益最大问题

问题描述:在T+1交易规则下,给出每天股票的买/卖价序列,要求在序列期间内最多只允许买、卖各一次,求此期间内的最大收益是多少(可以选择不卖,即收益为0)

比如:
(1)价格序列为[7,1,5,3,6,4],则最大收益为5,即选择第2天买入(买入价1)、第5天卖出(卖出价6)
(2)价格序列为[7,6,4,3,1],则最大收益率为0,即只能选择买入,但因为价格持续下降,所以无法卖出。

方案一:显然可以暴力求解,两层循环求出各买入/卖出可能下的收益情况,求出最大值即可

def MaxStockGain(prices:list):
    gains = []
    for i in range(0, len(prices)-1):
        for j in range(i+1,  len(prices)):
            gains.append(prices[j] - prices[i])

    max_gain = max(gains)
    return max(max_gain, 0)

print(MaxStockGain([7, 1, 5, 3, 6, 4]))   # 5
print(MaxStockGain([7, 6, 4, 3, 1]))     # 0

上述暴力法的计算复杂度为 O ( n 2 ) O(n^2) O(n2),那能否更简单的求解该问题呢?

方案二:线性扫描一遍列表,假设在位置 L ( i ) L(i) L(i)处卖出,则其买入点必然为前序列表处价格最低点处,而决定该点卖出是否划算只需对比此时卖出收益和前序卖出各方案的max值。

由此,引入两个状态量:
a [ i ] a[i] a[i]:从序列开始到 L ( i ) L(i) L(i)的最低价格(作为买入点)
b b b:从序列开始到 L ( i ) L(i) L(i)的最大收益值

状态迭代函数为:
a [ i + 1 ] = min ⁡ { a [ i ] , L [ i + 1 ] } a[i+1]=\min\{a[i], L[i+1]\} a[i+1]=min{a[i],L[i+1]}
b = max ⁡ { b , L [ i + 1 ] − a [ i + 1 ] } b=\max\{b, L[i+1]-a[i+1]\} b=max{b,L[i+1]a[i+1]}

初始条件为:
a [ 1 ] = L [ 1 ] a[1]=L[1] a[1]=L[1] b [ 1 ] = 0 b[1]=0 b[1]=0

据此,相应代码为:

def MaxStockGain(prices:list):
    min_price = prices[0]     # 记录到第i天时,所有天数里股票价格最大值,即买入点。初始值为第一天
    max_gain = 0      # 记录到第i天时,卖出的最大收益。初始值第一天买入后,一致持有的收益
    for p in prices[1:]:
        min_price = min(min_price, p)
        max_gain = max(max_gain, p - min_price)
    return max_gain
    
print(MaxStockGain([7, 1, 5, 3, 6, 4]))   # 5
print(MaxStockGain([7, 6, 4, 3, 1]))     # 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值