47.贪心算法之三:如果可以预知未来,股票最佳买卖时机问题

Posted 和孩子一起学Python

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了47.贪心算法之三:如果可以预知未来,股票最佳买卖时机问题相关的知识,希望对你有一定的参考价值。



    贪心算法的经典问题:股票最佳买卖时机问题。




    47.贪心算法之三:如果可以预知未来,股票最佳买卖时机问题


    股票最佳买卖时机问题是经典算法题之一。

    给定某只股票一段时间内每天的价格,如[8,9,2,4,10,12,13,24],问如何买卖使得收益最大。

    一般来说,由易到难,股票最佳买卖问题会有5种不同的问法

    1.只能买卖一次

    2.可以买卖任意多次

    3.只能买卖指定次数,比如只能买卖3次

    4.有冻结期,买卖一次之后,需要冻结几天才能进行下次买卖

    5.有手续费,每次买卖都有手续费。


    我们现在学的“贪心算法”,只能解决前2问。后面的问题,需要等到后面“动态规划算法”时再介绍。

    

    

暴力求解只能买卖一次问题


    只能买卖一次的问题看上去特别简单。

    找到最低价格,找到最高价格,用最高价格减去最低价格?

    比如[8,9,2,4,10,12,13,24],最高价24,最低价2,所以最多获利22元?


    真的是这样吗?

    如果股票的价格是这样呢?

    [8,24,2,4,10,12,13,9]

    很显然,在真实世界里,你不可能在第3天以2块钱的价格买入股票,再回到第2天以24元的价格卖出股票。


    当然,在[8,24,2,4,10,12,13,9]里,我们也很容易看出,第一天以8元的价格买入股票,第2天以24的价格卖出股票获利最大。

    但如果给你一年的股票价格,甚至2年的股票价格,你还能很容易看出来吗?


    这个时候,我们还是需要借助计算机,用Python来帮你完成这个问题。

    基于计算机强大的计算能力,这个问题用Python来做就简单了。


    假设是一年365天的股票价格。

    我们可以在任意一天买入股票,有364种可能。(最后一天买入没有意义)

    在买入股票之后的任意一天卖出股票。

    如果在第1天买入,卖出的日期有 364种可能。

    如果在第2天买入,卖出的日期有 363种可能。

    如果在第3天买入,卖出的日期有 362种可能。

    ……

    只要用所有可能的卖出价格-买入价格,就能找到最大获利了。


    程序如下:

 

import random

n = 365
prices = random.sample(range(1000), n)
maxV = -1000
for i in range(n-1):
for j in range(i+1, n):
maxV = max(maxV, prices[j] - prices[i])




贪心算法求解只买卖一次问题


    暴力求解的问题是时间复杂度是 O( n * n ),当数据量比较大的时候,计算的速度就会慢下来。

    而使用贪心算法的思想,我们可以把这个问题的时间复杂度降低到 O(n),极大提升计算速度。


    我们按如下思路进行思考。

    

    1.先不考虑买入,只考虑卖出的日期,有 n-1 种可能。

    如 [8,24,2,4,10,12,13,9],可能在第2天卖出,也可以在第3天卖出,也可以在第4天卖出,……


    2.如果确定了卖出日期,最大收益 = 卖出日期当天价格 - 当天之前的最低价格

    如 [8,24,2,4,10,12,13,9],假设确定在第5天卖出,第5天的价格是10,第5天之前的最低价是2。所以如果确定是第5天卖出,最大收益是 10 - 2 = 8


    3.把所有卖出日期的最大收益进行比较,选出其中最大的。就是问题所求。


    所以,我们只需要从第2天开始循环,假定是当天卖出股票,然后计算出当天卖出股票的最大收益,最后从中选出最大值。


    程序如下,只需要循环n-1次就可以了。

    

import random

minV = prices[0]
maxV = -1000
for i in range(1,n):
maxV = max(maxV,prices[i]-minV)
minV = min(minV,prices[i])
print(maxV)




贪心算法求解不限买卖次数问题


    贪心的思想更适合用来理解不限买卖次数的问题。

    如 [8,24,2,4,10,12,13,9],为了更便于理解,可以把每天的股票价格绘制成如下的折线图。

47.贪心算法之三:如果可以预知未来,股票最佳买卖时机问题


    在上图中,我们的贪心策略非常直白明显。

    “每次股票上涨的钱都要挣到,每次股票下跌都不能有损失”

    具体来说,就是 8块涨到24块的钱要挣到,24块跌到2块不能有损失,2块涨到4块,4块涨到10块,10块涨到12块,12块涨到13块的钱都要挣到,13块跌到9块不能有损失。


    写成程序,不就是如果后一天的股票价格比前一天的高,这个钱就得算我的,否则就不操作,没损失吗。

    

sumV = 0
for i in range(1,n):
if prices[i] > prices[i-1]:
sumV += prices[i] - prices[i-1]



特殊的大富翁游戏

    

    很多人小时候都玩过“大富翁”游戏,这是一款掷骰子跳着前进的游戏。


47.贪心算法之三:如果可以预知未来,股票最佳买卖时机问题


    现在假设有这么一种特殊的“大富翁”游戏。

    每一个格子上都有一个数字,表示你从这个格子上可以跳跃的最大长度。

    如下图:

    如果你站在第1个格子上,格子上的数字是3。

    表示你可以跳1格,达到第2个格子

    也可以跳2格,达到第3个格子

    也可以跳3格,到达第4个格子。

    但是你不能一次跳4格及以上

    

47.贪心算法之三:如果可以预知未来,股票最佳买卖时机问题

    

    如果格子里的数字都是非负的整数。

    问题1: 判断是否可以达到终点?

    问题2:达到终点最少的跳跃次数是多少次? 



    往期文章 https://dwz.cn/gBg1UPmk
    或关注公众号,点“原创文章”






扫描二维码

获取更多精彩

少儿编程


以上是关于47.贪心算法之三:如果可以预知未来,股票最佳买卖时机问题的主要内容,如果未能解决你的问题,请参考以下文章

121. 买卖股票的最佳时机简单贪心

121. 买卖股票的最佳时机简单贪心

「经典题目回顾」贪心算法:买卖股票的最佳时机II

贪心算法:买卖股票的最佳时机II

贪心算法 | leetcode 买卖股票系列

python买卖股票的最佳时机--贪心/蛮力算法简介