在采访中得到了这个问题。想知道是否有更好的解决方案:
鉴于股票的价格序列为[p1,p2,p3,p4,....对-N。交易员乔被要求在时间i买入1股股票,并在时间j卖出相同的股票。他的目标是最大化购买时间和销售时间之间的时间差距,但仍然有利可图。 例如,Trade Joe按时间顺序获得一系列价格:
时间,价格
10:00,10.3
10:01,10.1
10:02,11
10:03,13
10:04,9.5
10:05,7.3
10:06,8
10:07,10.2
10:08,9.8
如果他在10:01买入股票,价格= 10.1,并在10:07卖出,价格为10.2。他将获利0.1,买卖之间的时间为6分钟。这是这个例子的最长时间。
输入
第一行包含序列N的长度。接下来的N行包含(时间,价格)对: ñ 时间1,价格1 时间2,price2 ...
输出
使用给定的价格序列进行有利可图的买入 - 买出 - 卖出行动之间的最长时间
示例输入(使用文件或标准输入):
7
10:01,7
10:02,4
10:03,5
10:04,10
10:05,5
10:06,2
10:07,6
示例输出:
5(这是在10:02($ 4)使用买入,在10:07($ 6)卖出, 时间差是10:07 - 10:02 = 5分钟)
我提出的解决方案是O(N 2 ),只有一个小优化:
for(int i = 0; i < lines.size(); i++){
for(int j = lines.size()-1; j >= 0; j--){
try
{
String[] partsFirst = lines.get(i).split(",");
String[] partsLast = lines.get(j).split(",");
String firstPriceString = partsFirst[1];
String lastPriceString = partsLast[1];
String firstDateString = partsFirst[0];
String lastDateString = partsLast[0];
double firstPriceInt = Double.parseDouble(firstPriceString);
double lastPriceInt = Double.parseDouble(lastPriceString);
Date date1 = format.parse(firstDateString);
Date date2 = format.parse(lastDateString);
long difference = date2.getTime() - date1.getTime();
//optimization
if(difference <= maxDuration)
continue;
if(lastPriceInt > firstPriceInt && (difference) > maxDuration)
maxDuration = difference;
}
catch (ParseException ex)
{
System.out.println("Exception "+ex);
}
}
}
那里有更有效的解决方案吗?
答案 0 :(得分:4)
是的,有一个O(n)时间算法。
向前扫描价格(从头到尾),在辅助阵列中存储价格低于以前所有价格的价格,以及他们的时间。做类似的事情,发现所有价格都高于所有后续价格。这些数组都是自然排序的。
最优交易从第一个阵列购买并卖出到第二个。两个数组的变量排序合并将识别所有可盈利的O(n)交易,并且鉴于一个端点是固定的,最大距离。
合并的方式是我们将索引初始化为“买入”(第一个)数组,将另一个索引初始化为“卖出”(第二个)数组,从最低价格开始。如果当前买入价格低于当前卖出价格,则考虑该交易并继续下一个最高买入价格。否则,继续下一个最高卖价。
答案 1 :(得分:2)
以下是对David Eisenstat's Answer中提到的O(n)解决方案的解释。
这里的主要观察是,如果A点的时间比另一点B的价格低,那么A是比B更好的买点。例如,如果你有价格[2,3,4] ,1,...](按时间排序),如果您已经测试过,那么测试3和4作为购买点是没有意义的。我们可以得出结论,对于起点,我们只需要测试价格小于之前的所有价格。这可以通过扫描价格并保存符合该条件的点来完成。
这会给我们一个数组buy_points = [p 1 ,p 2 ,p 3 ,...]
第二个观察结果是,对于任何卖点,如果它的价格不高于买入点p i ,那么它不会高于任何先前的点数p j ,其中j <一世。这是因为购买点中的每个元素都小于之前的所有点。
鉴于这些观察结果,我们可以按如下方式构建算法:
我们向后扫描买点阵列和卖点阵列(原价格阵列)。对于每对售价和购买价格:
这是python中的示例代码:
def get_max_distance(prices):
min_price_so_far = None
buying_points = []
for time, price in prices:
if min_price_so_far is None or price < min_price_so_far[1]:
min_price_so_far = (time, price)
buying_points.append(min_price_so_far)
selling_points = reversed(prices)
buying_points = reversed(buying_points)
buying_point = next(buying_points, None)
selling_point = next(selling_points, None)
best = 0
while buying_point and selling_point:
buying_time, buying_price = buying_point
selling_time, selling_price = selling_point
if selling_price > buying_price:
if selling_time > buying_time:
best = max(best, selling_time - buying_time)
buying_point = next(buying_points, None)
else:
selling_point = next(selling_points, None)
return best