Algorithm 面试问题:最大多重销售利润
我在一次面试中遇到了一个关于算法的问题,但我似乎无法理解。我知道它应该如何工作,但无法从算法上对其进行排序 因此,假设一家公司交易石油桶,一次只能保留一个石油桶。假设公司知道一年中每天的每桶价格。所以它作为一个数组传入。如何编写一个算法来确定何时买卖 以下是一个5天的简化示例:Algorithm 面试问题:最大多重销售利润,algorithm,Algorithm,我在一次面试中遇到了一个关于算法的问题,但我似乎无法理解。我知道它应该如何工作,但无法从算法上对其进行排序 因此,假设一家公司交易石油桶,一次只能保留一个石油桶。假设公司知道一年中每天的每桶价格。所以它作为一个数组传入。如何编写一个算法来确定何时买卖 以下是一个5天的简化示例: 70 74 73 72 76,分别为周一至周五 在这里最好的做法是周一买入(70),周二卖出(74),然后周四买入(72),周五卖出(76)。应该递归地处理吗?我真的很想解决这个问题 谢谢,我想你是想利润最大化,对吗 在
70 74 73 72 76
,分别为周一至周五
在这里最好的做法是周一买入(70),周二卖出(74),然后周四买入(72),周五卖出(76)。应该递归地处理吗?我真的很想解决这个问题
谢谢,我想你是想利润最大化,对吗 在这种情况下,你只需在局部极小值买入,在局部极大值卖出,这将是一个简单的线性搜索 其实就是这么简单。证明: 让我们表示
p(i) ... the price of oil on day i
have(i) ... 1 if we retain the barrel overnight from day i to day i+1, 0 otherwise
M(i) = max(p(i+1) - p(i), 0)
have仅为[0,N-1]中的i定义
现在,如果我们在k
日买入,在l
日卖出,我们就会
have(k) = 1
have(l) = 0
have(i) = 1 for k < i < l
让我们表示
p(i) ... the price of oil on day i
have(i) ... 1 if we retain the barrel overnight from day i to day i+1, 0 otherwise
M(i) = max(p(i+1) - p(i), 0)
对于所有可能的布尔函数have
,我们有
profit(have) = sum over {i where have(i)==1} (p(i+1) - p(i))
<= sum over {i where have(i)==1} max(p(i+1) - p(i), 0)
<= sum over {i where have(i)==1} M(i)
<= sum over {i in [0, N-1]} M(i)
利润(have)=i上的和,其中have(i)=1}(p(i+1)-p(i))
p(i))
,它将拥有与上述相同的利润,这意味着它是最大的。此外,这意味着你可以按当地最低价格买进,按当地最高价格卖出。只要比较一下价格:
每周搜索最低价
(loop1)
(if currentPrice < nextPrice)
currentPrice = nextPrice
(循环1)
(如果当前价格
并获得currentPrice(日期)和nextLowerSellPrice之间的最高价格
(loop2)
(if currentHighPrice<nextHighPrice)
currentHighPrice = nextHighPrice
else
sell(currentHighPriceDay)
(loop2)
(如果currentHighPrice算法在O(N)时间和O(1)空间中:
Starting at index 0
If you haven't bought an oil barrel:
if price[i] < price[i + 1], buy at price[i]
// if price[i] >= price[i + 1], you will never buy at price[i]
// as price[i + 1] can bring you more money. So just wait...
If you have bought an oil barrel:
if price[i] > price[i + 1], sell at price[i]
// if price[i] <= price[i + 1], you will never sell at price[i]
// as price[i + 1] can bring you more money. So just wait...
以本地最大值卖出,以本地最小值买入。在开始前将价格视为无穷大,结束后将价格视为零。以你的例子或每桶价格:[70、74、73、72、76]
根据给定的价格,我可以计算每日价格变化(即今天的价格-前一天的价格)。在这种情况下,“价格变化数组”是[4,-1,-1,4]
在“价格变动数组”中,与前一天相比,正数表示价格上涨,负数表示价格下跌
解决方案是从“价格变化数组”中找出所有只包含正数的连续子数组
利用这个想法,我编写了以下python代码来打印购买日和相应的销售日对:
barrel_price = [70, 74, 73, 72, 76]
trading_days = {} #dictionary for storing {buy_day: sell_day}
buy_day=0
sell_day=buy_day+1
while sell_day < len(barrel_price):
if barrel_price[sell_day]-barrel_price[sell_day-1]>0:
#don't sell if price is still increasing
sell_day=sell_day+1
trading_days[buy_day] = sell_day-1
else:
#don't buy if price is still decreasing
buy_day=sell_day
sell_day=buy_day+1
print trading_days
barrel_价格=[70,74,73,72,76]
交易日={}}存储{买入日:卖出日}的字典
购买日=0
卖出日=买入日+1
销售日0:
#如果价格还在上涨,就不要卖
卖出日=卖出日+1
交易日[买入日]=卖出日-1
其他:
#如果价格还在下降,就不要买
买入日=卖出日
卖出日=买入日+1
打印交易日
这将打印“{0:1,3:4}
”
对于第一对0:1,即第0天买入和第1天卖出,对应的价格为每桶价格数组中的70和74。
对于下一对3:4,相应的买入价为72,卖出价为76。L[j]表示截至第j天的利润。
L[j]=L[j-1]+MAX(0,Pj-Pj-1)
Pj=第j天的股价。
解决方案在于L[n],因为每个L[j]给出了到该点为止的最大利润,而L[n]给出了最后一天的最大利润。
运行时间:O(n)这是任何投资公司中他们问你的最常见、最明显的问题。如果你在面试中不能回答这个问题,那么你就没有做足够的研究和准备。参见uplicate@Suraj钱德兰:我已经习惯了更多的数学/数学问题。现在我正在尝试更多的金融与数学/数学相关的问题。你如何找到这样的dup太快了我在stack overflow上研究了一段时间来研究一个类似的问题。我觉得这不像是重复的问题,链接的问题只有一个买入/卖出。@Navefc…我与一家投资公司合作:(…无论如何,只需搜索“最大化卖出-买入算法”@苏拉杰·钱德兰:这不是一个重复的IIUC。另一个问题是要最大化一笔交易,这一笔交易允许多笔交易。@nayefc-你能解释一下这里的问题吗?这对我来说似乎是一个有效的答案。我不明白你是如何找到本地MIN和MAXE的。你能为OP的例子提供一个算法运行示例吗?是吗假设交易策略中允许这样的预测?事后诸葛亮是20-20。如果第n+1天的价格高于第n天,那么你想在第n天拥有一桶——否则不行。如果你想在某一天拥有一桶的愿望与前一天的愿望不同,那么你需要进行交易来解决这种情况。@jpalecek:好的,“求和结束”是什么意思,为什么我们需要它?我理解这个部分直到M(I)=max(p(I+1)-p(I),0)。有人能帮助algo获得利润吗?看看OP的例子就知道这是失败的。
barrel_price = [70, 74, 73, 72, 76]
trading_days = {} #dictionary for storing {buy_day: sell_day}
buy_day=0
sell_day=buy_day+1
while sell_day < len(barrel_price):
if barrel_price[sell_day]-barrel_price[sell_day-1]>0:
#don't sell if price is still increasing
sell_day=sell_day+1
trading_days[buy_day] = sell_day-1
else:
#don't buy if price is still decreasing
buy_day=sell_day
sell_day=buy_day+1
print trading_days