Python算法学习day4:关于一道亚马逊面试题的情景分析

题目描述

亚马逊是一家纳斯达克上市公司,通过其财报我们可以解读它在给定时期内的股票走势信息。
这些信息包括每天交易的最高价、最低价以及开盘价。假定你作为交易员,必须在股票开盘时做出买入或卖出的决定。
你负责设计一个算法,根据给定的股价走势信息,决定买入和卖出策略,该策略必须保证你的交易获得的利润最大化。
假设S数组有以下9个数值[10,4,8,7,9,6,2,5,3]

1. 暴力枚举法

# S定义股票开盘价
S = [10,4,8,7,9,6,2,5,3]

maxProfit = 0
buyDay = 0
sellDay = 0
# 暴力枚举
for i in range(len(S) - 1):
	for j in range(i+1, len(S)):
		if S[j] - S[i] > maxProfit:
			maxProfit = S[j] - S[i]
			buyDay = i
			sellDay = j
print("应该在第{0}天买入, 第{1}天卖出, 最大交易利润为: {2}").format(buyDay+1, sellDay+1, maxProfit))

算法时间复杂度为O(n*n)

2. 分而治之法

分别计算前半部分和后半部分的最大交易利润,然后在两者中选择出较大的那个,最后还要考虑一种临界情况,那就是最大利润在前半部分的某一天买入,后半部分的某一天卖出
代码实现:

def findMaxProfit(S):
	if len(S) < 2:
		return [0,0,0]
	if len(S) == 2:
		if (S[1] > S[0]):
			return 	[0,1,S[1] - S[0]]
		else :
			return [0,0,0]
	# 把交易数据分成两部分
	firstHalf = findMaxProfit(S[0:int(len(S) / 2)])
	secondHalf = findMaxProfit(S[int(len(S) / 2):len(S)])
	finalResult = firstHalf
	
	if (SecondHalf[2] > firstHalf[2]):
		# 后半部分的交易日期还要加上前半部分的天数
		secondHalf[0] += int(len(S) / 2)
		secondHalf[1] += int(len(S) / 2)
		finalResult = secondHalf
	# 看最大利润方案是否是在前半部分买入, 后半部分卖出 
	
	lowestPrice = S[0]
	highestPrice = S[int(len(S) / 2)]
	buyDay = 0
	selDay = int(len(S) / 2)
	for i in range(0, int(len(S) / 2)):
		if (S[i] < lowestPrice):
			buyDay = i
			lowestPrice = S[i]
		for i in range(int(len(S) / 2), len(S)):
			if (S[i] > highestPrice):
				selDay = i
				highestPrice = S[i]
		if (highestPrice - lowestPrice > finalResult[2]):
			finalResult[0] = buyDay
			finalResult[1] = selDay
			finalResult[2] = highestPrice - lowestPrice
		return finalResult
		
S = [10,4,8,7,9,6,2,5,3]
maxProfit = findMaxProfit(S)
print("应该在第{0}天买入, 第{1}天卖出, 最大交易利润为: {2}").format(buyDay+1, sellDay+1, maxProfit))

3. 最优解法

假设最佳交易方案是第N天卖出, 那么最佳的买入时机就是前N-1天价格最低的时候

S = [10,4,8,7,9,6,2,5,3]
minPrice = S[0]

N = 0

maxProfit = 0
buyDay = 0
sellDay = 0

for N in range(len(S)):
	if (S[N] < minPrice):
		minprice =S[N]
		buyDay = N
	
	if (S[N] - minPrice > maxProfit):
		maxProfit = S[N] - minPrice
		selDay = N
print("应该在第{0}天买入, 第{1}天卖出, 最大交易利润为: {2}").format(buyDay+1, sellDay+1, maxProfit))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值