如何提高该算法的时间复杂度以找到最高股价?

时间:2018-10-07 06:58:44

标签: python algorithm time-complexity

我目前通过了样本测试,其余10个案例中有2个通过了,所以12个中有4个通过。但是,我没有通过所有数据。由于超时错误,我正在终止,这意味着我的解决方案不够快。

def stockmax(prices):
    total = 0 
    for index, price in enumerate(prices):
        if index < len(prices) - 1: 
            section = max(prices[index+1:])

            if prices[index] < section:
                total += section - prices[index]
    return total

我试图只做一次循环。但是究竟怎样才能加快此类问题的速度呢?我也尝试削减一些代码行,但这同样效率低下。

def stockmax(prices):
    total = 0 
    for index, price in enumerate(prices):
        if index < len(prices) - 1 and prices[index] < max(prices[index+1:]): 
              total += max(prices[index+1:]) - prices[index]
    return total

尽管它通过了相同数量的测试用例。 我也尝试使用heapq,但是它通过了相同的测试用例,并且由于时间而失败。

def stockmax(prices):
    total = 0 
    for index, price in enumerate(prices):
        if index < len(prices) - 1:
            section = heapq.nlargest(1,prices[index+1:])[0]
            if prices[index] < section: 
                total += section - prices[index]
    return total

https://www.hackerrank.com/challenges/stockmax/topics/dynamic-programming-basics 有关该问题的详细信息。
https://hr-testcases-us-east-1.s3.amazonaws.com/330/input09.txt?AWSAccessKeyId=AKIAJ4WZFDFQTZRGO3QA&Expires=1538902058&Signature=3%2FnfZzPO8XKRNyGG0Yu9qJIptgk%3D&response-content-type=text%2Fplain 一些测试用例的链接,但过一会就会过期。

问题

您的算法已经很好地预测市场了,您现在知道木制橙牙签公司(WOT)在未来几天的股价将是什么。

每天,您可以购买一股WOT,出售您拥有的任意数量的WOT股票,或者根本不进行任何交易。最佳交易策略可获得的最大利润是多少?

例如,如果您知道接下来两天的价格为prices = [1,2],则应该在第一天买入一股股票,然后在第二天卖出以赚取1的利润。如果价格是{{1} },无法获得任何利润,因此您那几天不会买卖股票。

功能说明

在下面的编辑器中完成stockmax函数。它必须返回一个代表可以实现的最大利润的整数。

prices = [2,1]具有以下参数:

价格:代表预计每日股票价格的整数数组

输入格式

第一行包含测试用例的数量stockmax

接下来的t对行中的每对包含:

  • 第一行包含一个整数t,即WOT的预测价格数。
  • 下一行包含n个以空格分隔的整数n,每个整数都是当日prices [i]的预测股价。

约束

i

输出格式

输出行,每行包含可从相应测试用例获得的最大利润。

样本输入

1 <= t  <= 10
1 <= n <= 50000
1 <= prices [i] <= 100000

样本输出

3
3
5 3 2
3
1 2 100
4
1 3 1 2

说明

在第一种情况下,您无法获得任何利润,因为股价从未上涨。 对于第二种情况,您可以在前两天购买一股股票,并在第三天出售它们。 对于第三种情况,您可以在第1天买入一股,在第2天买入一股,在第3天买入一股,然后在第4天卖出一股。

3 个答案:

答案 0 :(得分:2)

很明显,对于我们能买到的任何价格,我们都想以最高价出售。幸运的是,我们获得了最高的价格。因此,向后迭代,我们知道在旅行中“时光倒流”的任何时候看到的最高未来价格。

Python代码:

def stockmax(prices):
  n = len(prices)
  highest = prices[n - 1]
  m = [0] * n

  # Travel back in time,
  # deciding whether to buy or not
  for i in xrange(n - 2, -1, -1):

    # The most profit buying stock at this point
    # is what we may have made the next day
    # (which is stored in m[i + 1])
    # and what we could make if we bought today
    m[i] = m[i + 1] + max(
      # buy
      highest - prices[i],
      # don't buy
      0
    )

    # Update the highest "future price"
    highest = max(highest, prices[i])

  return m[0]

答案 1 :(得分:0)

如果您可以使用Numpy,则与以下内容类似的操作应该很快(我认为这与@גלעדבבקן的答案是相同的想法)。

import numpy as np

with open('.../input09.txt') as fd:
    numtests = int(fd.readline().strip())
    counter = 0
    numvals = 0
    vals = None
    steps = None
    for line in fd:
        if (counter % 2 == 0) :
            numvals = int(line.strip())
        else:
            vals = np.fromstring(line, dtype=int, sep=' ', count=numvals)
            assert len(vals) == numvals

            cum_max = np.maximum.accumulate(vals[::-1])
            np.roll(cum_max, -1)
            cum_max[len(cum_max) - 1] = 0
            delta = (cum_max - vals)
            print('#', counter + 1, 'sum:', np.sum(delta * (delta > 0)))

        counter += 1

它几乎可以在input09.txt上的测试中立即运行。

答案 2 :(得分:0)

这是我用红宝石写的解决方案。 该解决方案获得了满分。

def solution(a)
  gain = 0
  i = a.count - 1
  min = false
  mi = false

  while i > 0
    s = a.delete_at(i)

    unless min
      mi = a.index(a.min)
      min = a[mi]
    end
    g = s - min
    gain = g if g > gain
    i -= 1
    min = false if i == mi
  end
  gain
end