47.贪心算法之三:如果可以预知未来,股票最佳买卖时机问题
Posted 和孩子一起学Python
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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],为了更便于理解,可以把每天的股票价格绘制成如下的折线图。
在上图中,我们的贪心策略非常直白明显。
“每次股票上涨的钱都要挣到,每次股票下跌都不能有损失”
具体来说,就是 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]
很多人小时候都玩过“大富翁”游戏,这是一款掷骰子跳着前进的游戏。
。
现在假设有这么一种特殊的“大富翁”游戏。
每一个格子上都有一个数字,表示你从这个格子上可以跳跃的最大长度。
如下图:
如果你站在第1个格子上,格子上的数字是3。
表示你可以跳1格,达到第2个格子
也可以跳2格,达到第3个格子
也可以跳3格,到达第4个格子。
但是你不能一次跳4格及以上
如果格子里的数字都是非负的整数。
问题1: 判断是否可以达到终点?
问题2:达到终点最少的跳跃次数是多少次?
扫描二维码
获取更多精彩
少儿编程
以上是关于47.贪心算法之三:如果可以预知未来,股票最佳买卖时机问题的主要内容,如果未能解决你的问题,请参考以下文章