一些背景
我试了试常见的"maxprofit";编程挑战。它基本上是这样的:
给定一个由N个包含daily的整数组成的零索引数组a某只股票的价格连续N天上涨,即有回报在此期间从一笔交易中可能获得的最大利润。
我对自己提出的这个PHP算法非常满意,它避免了幼稚的暴力尝试:
public function maxProfit($prices)
{
$maxProfit = 0;
$key = 0;
$n = count($prices);
while ($key < $n - 1) {
$buyPrice = $prices[$key];
$maxFuturePrice = max( array_slice($prices, $key+1) );
$profit = $maxFuturePrice - $buyPrice;
if ($profit > $maxProfit) $maxProfit = $profit;
$key++;
}
return $maxProfit;
}
然而,在测试了我的解决方案之后,它似乎在性能方面表现很差,甚至可能在O(n2)时间内。
我做了一些关于这个主题的阅读,发现了一个非常相似的python解决方案。Python有一些非常方便的数组功能,允许使用a[s : e]
语法拆分数组,不像在PHP中我使用array_slice
函数。我认为这一定是瓶颈,所以我做了一些测试:
PHP array_slice ()
$n = 10000;
$a = range(0,$n);
$start = microtime(1);
foreach ($a as $key => $elem) {
$subArray = array_slice($a, $key);
}
$end = microtime(1);
echo sprintf("Time taken: %sms", round(1000 * ($end - $start), 4)) . PHP_EOL;
结果:
$ php phpSlice.php
Time taken: 4473.9199ms
Time taken: 4474.633ms
Time taken: 4499.434ms
Python a[s: e]
import time
n = 10000
a = range(0, n)
start = time.time()
for key, elem in enumerate(a):
subArray = a[key : ]
end = time.time()
print "Time taken: {0}ms".format(round(1000 * (end - start), 4))
结果:
$ python pySlice.py
Time taken: 213.202ms
Time taken: 212.198ms
Time taken: 215.7381ms
Time taken: 213.8121ms
问题- 为什么PHP的
- 在PHP中是否有同样有效的方法实现上述目标,从而有希望使我的
maxProfit
算法在O(N)时间内运行?编辑我意识到我上面的实现实际上不是O(N),但我的问题仍然是关于切片数组的效率。
array_slice()
比Python的效率低20倍?- 我真的不知道,但PHP的数组是混乱的混合怪物,也许这就是为什么。Python的列表实际上只是列表,而不是字典,因此它们可能更简单/更快。
- 是的,做一个实际的O(n)解决方案。你的解决方案慢并不是因为PHP的切片慢,而是因为你显然有一个O(n^2)算法。只需遍历数组一次,跟踪到目前为止找到的最小价格,并将其与当前价格进行检查。而不是像
max
在每次循环迭代中超过一半的数组。