algorithm - 最大化给定股票报价的利润

标签 algorithm recursion dynamic-programming

<分区>

我在面试一家初创公司时被问到这个问题,并在最近的竞赛中再次看到了这个问题

Code Sprint:systems

**问题:

给定了几天的股票价格。每天,您可以买入一个单位的股票,卖出您已经买入的任意数量的股票单位,或者什么都不做。通过优化您的交易策略,您可以获得的最大利润是多少?**

示例(输入即天数可以变化)

5 3 2 => profit = 0//由于价格每天都在下降,我们可以赚取的最大利润 = 0

1 2 100 => 利润 = 197

1 3 1 2 =>profit = 3//我们在 1 买入,在 3 卖出,然后我们在 1 买入,在 2 卖出 ..total profit = 3

我的解决方案:

a) 找到股票价格最高的那一天。直到那天继续购买 1 个单位的股票。

b) 如果那天是最后一天,则退出:

其他: 当天卖出所有股票,当天之后拆分数组并对剩余元素进行递归
c) 合并利润

例如 1 4 1 2 3
a) 第 2 天的最高股价 .. 所以我们在第 1 天买入股票并在第 2 天卖出(利润 = 3)然后我们在剩余的几天递归:1 2 3

b) 最高价格为 3(第 5 天),因此我们在第 3 天和第 4 天继续买入股票,并在第 5 天卖出(利润 = ( 3*2 - 3 = 3 )

c) 总利润 = 3 + 3 = 6

结果复杂度为 O(n^2) 。该解决方案通过了 11 个案例中的 10 个,但超过了最后一个测试案例(即最大输入)的时间限制

谁能想出更有效的解决方案来解决这个问题?是否有动态规划解决方案?

最佳答案

我同意你方法的逻辑,但不需要进行递归处理或全局最大值搜索。要查找卖出/买入日,您只需每天查看一次:

诀窍是从头开始。 如果您时光倒流,股票交易会很容易!

如果你认为代码比文字更容易阅读,请跳过我的解释,但这里是:

读到最后,看当天的价格。这是目前为止(从末尾算起)的最高价吗,那就卖吧!最后一天(我们开始阅读的地方)你总是会卖出。

然后转到第二天(记住,时间向后)。这是迄今为止的最高价格吗(从我们看过的所有价格来看)? - 然后全部卖掉,你不会找到更好的日子。否则价格上涨,所以买。以同样的方式继续,直到开始。

整个问题通过一个反向循环解决:计算决策和交易利润。

这是类 C python 中的代码:(我避免了大多数 pythonic 的东西。对于 C 语言的人来说应该是可读的)

def calcprofit(stockvalues): 
    dobuy=[1]*len(stockvalues) # 1 for buy, 0 for sell
    prof=0
    m=0
    for i in reversed(range(len(stockvalues))):
        ai=stockvalues[i] # shorthand name
        if m<=ai:
            dobuy[i]=0
            m=ai
        prof+=m-ai
    return (prof,dobuy)  

例子:

calcprofit([1,3,1,2]) gives (3, [1, 0, 1, 0])
calcprofit([1,2,100]) gives (197, [1, 1, 0])
calcprofit([5,3,2])   gives (0, [0, 0, 0])
calcprofit([31,312,3,35,33,3,44,123,126,2,4,1]) gives
 (798, [1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0])

请注意,m 是我们看到的最高股价(从末尾开始)。如果 ai==m 则在这一步购买股票的利润为 0:我们在该点之后价格下跌或稳定并且没有购买。

您可以通过一个简单的循环来验证利润计算是否正确(为简单起见,假设它在上述函数内)

stock=0
money=0
for i in range(len(stockvalues)):  
    if dobuy[i]:
        stock+=1
        money-=stockvalues[i]
    else:
        money+=stockvalues[i]*stock
        stock=0
print("profit was: ",money)

关于algorithm - 最大化给定股票报价的利润,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9514191/

相关文章:

algorithm - 是否有强一致的组成员协议(protocol)?

c++ - 在 C++ 中创建 n 个项目的所有可能的 k 个组合

java - 单根有向无环图环检测

algorithm - 找不到可以找到为产品列表应用优惠券代码的最佳方式的算法

c - 将数组划分为 K 个子数组,差异最小

c++ - 算法永远运行的整数排列

algorithm - N皇后递归程序

java - 简单循环时间复杂度内的递归函数

algorithm - 如何在线性时间内找到树中的最短简单路径?

python - 原始计算器的动态规划