Algorithm 面试问题:最大多重销售利润

Algorithm 面试问题:最大多重销售利润,algorithm,Algorithm,我在一次面试中遇到了一个关于算法的问题,但我似乎无法理解。我知道它应该如何工作,但无法从算法上对其进行排序 因此,假设一家公司交易石油桶,一次只能保留一个石油桶。假设公司知道一年中每天的每桶价格。所以它作为一个数组传入。如何编写一个算法来确定何时买卖 以下是一个5天的简化示例: 70 74 73 72 76,分别为周一至周五 在这里最好的做法是周一买入(70),周二卖出(74),然后周四买入(72),周五卖出(76)。应该递归地处理吗?我真的很想解决这个问题 谢谢,我想你是想利润最大化,对吗 在

我在一次面试中遇到了一个关于算法的问题,但我似乎无法理解。我知道它应该如何工作,但无法从算法上对其进行排序

因此,假设一家公司交易石油桶,一次只能保留一个石油桶。假设公司知道一年中每天的每桶价格。所以它作为一个数组传入。如何编写一个算法来确定何时买卖

以下是一个5天的简化示例:
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