在股票价值数组中查找买入/卖出价格以最大化正差

Posted

技术标签:

【中文标题】在股票价值数组中查找买入/卖出价格以最大化正差【英文标题】:Find buy/sell prices in array of stock values to maximize positive difference 【发布时间】:2010-12-12 10:08:07 【问题描述】:

今天面试被问到这个问题,它的优化解决方案让我不寒而栗(吹,因为我真的很想在这家公司工作......)

给定一组实际值,每个值代表任意时间段后公司的股票价值,找到最佳买入价及其对应的最佳卖出价(低买高卖)。

举个例子,我们以Z公司的股票代码为例:

55.39 109.23 48.29 81.59 105.53 94.45 12.24

需要注意的重要一点是数组在时间上是“排序的” - 即随着时间的推移,值会附加到数组的右端。因此,我们的买入价值将(必须)在我们卖出价值的左侧。

(在上面的例子中,理想的解决方案是在48.29 买入并在105.53 卖出)

我很容易就 O(n2) 复杂度(用 java 实现)想出了简单的解决方案:

// returns a 2-element array: first element is the index in the argument array
// of the best buying price, and the second element is the index of the best
// selling price which, collectively, maximize the trading return
//
// if there is no favorable trading (e.g. prices monotonically fall), null is returned
public int[] maximizeReturn(ArrayList<Double> prices) 
  int [] retval = new int[2];
  int BUY = 0, SELL = 1;
  retval[BUY] = retval[SELL] = -1; // indices of buy and sell prices, respectively

  for (int i = 0; i < prices.size(); i++) 
    for (int j = i + 1; j < prices.size(); j++) 
      double difference = prices.get(j).doubleValue() - 
                          prices.get(i).doubleValue();

      if (difference > 0.0) 
        if (retval[BUY] < 0 || difference > prices.get(retval[SELL]).doubleValue() - 
                                            prices.get(retval[BUY]).doubleValue()) 
          retval[BUY] = i;
          retval[SELL] = j;
        
      
    
  
  return (retval[BUY] > 0 ? retval : null);

这就是我搞砸的地方:有一个线性时间 O(n) 解决方案,我完全想弄清楚它(是的,我知道,失败)。有谁知道如何实现线性时间解决方案? (任何您喜欢的语言)谢谢!

编辑

我想,对于任何感兴趣的人,我今天刚刚收到消息说我没有得到我面试的工作,他们问我这个问题。 :(

【问题讨论】:

我想看看这个的一些功能性实现......让我想起功能性人以一种棘手的方式做得很好...... 我敢打赌你在彭博接受采访,嗯? 干得好,别担心工作,工作面试变化无常,真的不能很好地衡量现实世界的表现 【参考方案1】:

在 C# 中:

static void Main(string[] args)

    double[] values = new double[7]55.39, 109.23, 48.29, 81.59, 105.53, 94.45, 12.24;

    double max = double.MinValue, maxDiff = double.MinValue, diff = 0;

    for (int i = 1; i < values.Length; i++)
    
        if (values[i] > values[i - 1])
        
            //trending upward, append to existing differential
            diff += values[i] - values[i - 1];
        
        else
        
            //trending downward, reset the diff
            diff = 0;
        

        if (diff > maxDiff)
        
            maxDiff = diff;
            max = values[i];
        
    

    Console.WriteLine("Buy at 0; Sell at 1", max - maxDiff, max);

编辑:基于@Joe 失败的测试用例的新算法 -- Nice Catch BTW!这也与@Doug T 现在的答案相同......

static void Main(string[] args)

    double[] values = new double[8]  55.39, 109.23, 48.29, 81.59, 81.58, 105.53, 94.45, 12.24 ;

    double max = double.MinValue, maxDiff = double.MinValue, diff = 0;
    double bottom = values[0];

    for (int i = 1; i < values.Length; i++)
    
        diff += values[i] - values[i - 1];

        if (diff > maxDiff)
        
            maxDiff = diff;
            max = values[i];
        

        if (values[i] < bottom)
        
            bottom = values[i];
            diff = 0;
        
    

    Console.WriteLine("Buy at 0; Sell at 1", max - maxDiff, max);

【讨论】:

我想在显示它们之前应该检查一下 max 和 maxDiff 实际上是 set 的(对于排序的降序列表),但我们会乐观地认为股票至少有一个很好的会议...... 我真的很喜欢这个;我没有想到增加差异的想法。非常优雅! 这对于输入 55.39, 109.23, 48.29, 81.59, 81.58, 105.53, 94.45, 12.24 似乎失败了?最好还是在 48.29 买入并在 105.53 卖出(57.24 利润),但它说在 55.39 买入并在 109.23 卖出(53.84 利润) 是的,小幅下跌会混淆这个算法。 实际上是的,这个解决方案似乎有一个缺陷,即如果您向下趋势然后立即再次回升,但底部是在您向下趋势之前,您的差异被重置,您将看不到机会。 ..【参考方案2】:

这是一个尝试 (C++)。基本上每次我追踪一个新的顶部时,我都会尝试看看这是否是迄今为止最好的利润。我知道“底部”一定是更早发现的。那时我记得顶部、底部和当前的最大利润。如果以后发现新的底部,它在当前顶部之后,所以我们必须重新设置顶部,看看稍微低一点的“顶部”是否可以产生更好的利润。

#include <iostream>

int main()


    double REALLY_BIG_NO = 1e99;
    double bottom = REALLY_BIG_NO; // arbirtrary large number
    double currBestBuy = 0.0;
    double top = 0.0;
    double currBestSell = 0.0;
    double profit = 0.0;

    // array of prices
    double prices[] = 10.50, 55.39, 109.23, 48.29, 81.59, 105.53, 94.45, 12.24, 152.0, 2, 170.0;
    int numPrices = 10;// number of prices

    for (int i = 0; i < numPrices; ++i)
    
         if (prices[i] < bottom)
         
            bottom = prices[i];
            // reset the search on a new bottom
            top = 0.0;
         
         else if (prices[i] > top)
         
            top = prices[i];
           // calculate profit
            double potentialProfit = (top - bottom);
            if (potentialProfit > profit &&
                bottom != REALLY_BIG_NO)
            
                profit = potentialProfit;
                currBestSell = top;
                currBestBuy = bottom;
            
         
    

    std::cout << "Best Buy: " << currBestBuy << "Best Sell: " << currBestSell << std::endl;

到目前为止,我已经使用了一堆不同的输入集,到目前为止我还没有遇到任何问题...(如果您对此进行测试并发现任何问题,请告诉我)

我强烈建议使用 Austin Salonen 对此问题的更新答案并将其调整为适合您的语言。

【讨论】:

我正在慢慢接近像这样的解决方案,因为我摸索着前进;我和你一样设置了五个变量。不幸的是,我开始进行一些疯狂的价值交换,并且几乎从那里走到了尽头。 =/ 我重建了我的算法,现在它和你的一样...不同的语言和一些非常好的 cmets,所以我会留下它。 这在您交换 152.0 和 170.0 时不起作用(即当股票 = 10.50, 55.39, 109.23, 48.29, 81.59, 105.53, 94.45, 12.24, 170.0, 2, 152.0 时);跨度> 【参考方案3】:

这个想法很简单。保留两个指针,lo 和 hi。 做一个Foo循环

    如果价格高于 hi,更新 hi = price,继续 如果价格低于hi。那么 lo 和 hi 是可能的候选人之一。计算利润,如果它大于之前的利润,则将其存储,然后将 lo, hi 重置为价格

def getBestProfit(价格): lo = hi = 利润 = 0 for price in prices: if lo == 0 and hi == 0: lo = hi = price if price > hi: hi = price if price < low: tmpProfit = hi - lo if tmpProfit > profit: profit = tmpProfit lo = hi = price return profit

就是这样

【讨论】:

【参考方案4】:
void getBestTime (int stocks[], int sz, int &buy, int &sell)
int min = 0;
int maxDiff = 0;
buy = sell = 0;
for (int i = 0; i < sz; i++) 

    if (stocks[i] < stocks[min])
    
        min = i;
    
    int diff = stocks[i] - stocks[min];
    if (diff > maxDiff) 
    
        buy = min;
        sell = i;
        maxDiff = diff;
    

以防万一您更喜欢这个答案。我在另一个网站上找到了它,但仍然如此。 来源:http://leetcode.com/2010/11/best-time-to-buy-and-sell-stock.html

【讨论】:

【参考方案5】:
      public void profit(float stock[], int arlen )
            float buy = stock[0];
            float sell = stock[arlen-1];
            int bi = 0;
            int si = arlen - 1;

            for( int i = 0; i < arlen && bi < si ; i++)

                    if( stock[i] <  buy && i < si)
                            buy = stock[i];
                            bi = i;
                    
                    if(stock[arlen - i - 1] > sell &&  (arlen - i -1)  > bi)
                            sell = stock[arlen - i - 1];
                            si = arlen - i - 1;
                    
            
            System.out.println(buy+" "+sell);
    

【讨论】:

【参考方案6】:

我真的必须指出,作为一个面试问题,希望你能解决它,因为 O(n) 是荒谬的。面试问题旨在证明您可以解决问题,并且您能够解决它。您在 O(N^2) 与 O(N) 中解决它的事实应该是无关紧要的。如果一家公司因为没有在 O(N) 中解决这个问题而放弃雇用你,那可能不是你本来想工作的公司。

【讨论】:

“你在 O(N^2) 与 O(N) 中解决它的事实应该是无关紧要的。” - 我真的希望你是对的 :) 作为一名面试官,通常对推动面试者很有用。在其他条件相同的情况下,如果只有 1 个位置是开放的,考虑到 O(n) 求解器和 O(n^2) 求解器之间的选择,我将采用 O(n) 求解器。话虽这么说,我很高兴这些天我采访了一个从 O(n^2) 知道 O(n) 的人,所以你可能会得到我工作的工作! @Doug,问题是先解决问题。除非我们将现代计算机的 N 转换为 *illions,否则线性时间和二项式时间的差异应该可以忽略不计。这也与避免早期优化有关,如果他们问了一个可以通过递归轻松解决的问题,是使用优雅的方法还是花时间编写它更好,以便它可以在循环中完成而不是在需要之前递归完成?优化总是可以在以后进行。 作为面试官,我会说提出这个问题是一个很好的工具:1)如果他们甚至无法编写 O(n^2) 解决方案,他们就不是程序员. 2) 如果他们已经看到 O(n) 解决方案,那只意味着他们已经做了很多阅读(这真的是一个晦涩难懂的“AHA”类问题)。 3)如果他们没有,那么通过试图找到它的思考过程应该非常有启发性。 你对这个职位一无所知,也不知道员工将面临什么样的挑战。也许对于这项工作来说,最重要的技能是最小化算法的顺序,因为它们的数据量很大,并且计算的延迟要求很低。也许这种工作正是 OP 想要为之工作的那种公司。您如何断言哪些技能“应该与任何给定的公司和任何给定的职位无关”?更不用说哪些人会认为一家公司“不是 [他们] 本来想工作的公司”?【参考方案7】:

我想描述一下我是如何解决这个问题的,以便更容易理解我的代码:

(1) 对于每一天,如果我必须在那天卖出我的股票,我可以支付的最低购买金额是多少?本质上,我会在那天之前跟踪最低价格

(2) 对于每一天,如果我在那天卖出,我能赚多少钱? (当日股价-最低价)

这表明我必须跟踪两件事:(1) 迄今为止的最低股价 (2) 迄今为止的最佳收益。

问题变成了选择哪一天出售。我会在能给我带来最好收入的那一天卖出。这是我的 Java 代码:

    public static void findBestDeal(double [] stocks) 
    double minsofar = stocks[0];
    double bestsofar = 0.0;

    for(int i=1; i< stocks.length; i++) 

        // What is the cheapest price to buy it if I'm going to sell it today
        if(stocks[i-1] < minsofar) 
            minsofar = stocks[i-1];
        

        // How much do I earn if I sell it on ith day?
        double current_deal = stocks[i] - minsofar;

        // Is selling today better?
        if(current_deal > bestsofar) 
            bestsofar = current_deal;
        
    

    System.out.println("Found the best deal: " + bestsofar + " (Bought at " + minsofar + " and sold at " + (minsofar+bestsofar) + ")");


【讨论】:

【参考方案8】:

这是我的 O(n) 实现。我正在使用更改数组来计算最大利润和买卖日期。 欢迎您的参与。

#include<stdafx.h>
#include<stdio.h>

int main()

    //int arr[10] = 15, 3, 5,9,10,1,6,4,7,2;
    int arr[7] = 55.39, 109.23, 48.29, 81.59, 105.53, 94.45, 12.24;
    int change[7];
    int n=7;
    for(int i=1;i<=n;i++)
    
    change[i] = arr[i]- arr[i-1];
    
    int i=0,index = 0;
    int sum = 0;
    int maxsum = 0;
    int startpos = 0;
    int endpos = 0;
    while(index < n)
    
        sum = sum + change[index];
        if(maxsum < sum)
        
        maxsum = sum; 
        startpos = i;
        endpos = index;

        
        else if (sum<0) // negative number ,set sum to zero
        
        sum = 0;
        i=index+1;
        
        index++;
    

    printf("max profit is%d %d %d", maxsum , startpos, endpos+1 );

【讨论】:

【参考方案9】:

在我努力学习围棋的过程中,也为了在这个问题上绞尽脑汁,这是我的尝试。

func GetMaxProfit2(prices []float64) (float64, float64) 
    var min, max, pmin, pmax int

    for i, v := range prices 
        if v - prices[min] > prices[max] - prices[min] 
            pmax = max
            max = i
        
        // Reset the max when min is updated.
        if v < prices[min] 
            pmin = min
            min = i
            pmax = max
            max = i
        
    

    // If min is ahead of max, reset the values back    
    if min >= max 
        min = pmin
        max = pmax
    

    return prices[min], prices[max]

【讨论】:

【参考方案10】:

这是我使用 javascript 的尝试。该脚本以 O(N) 计算答案:

//Main Stock Array
var stock = [15, 20, 0, 3, 30, 45, 67, 92, 1, 4, 99];


//Setup initial variable state
var ans = , tmp = ; //These are just for namespacing / syntatic sugar
ans.minVal = stock[0];
ans.minInd = 0;
ans.maxDiff = stock[1] - stock[0];
ans.maxInd = 1;
tmp.minInd = ans.minInd;
tmp.minVal = ans.minVal;

//Basically we iterate throught the array. If we find a new low, we start tracking it. Otherwise we compare the current index against the previously found low
for(i = 1; i <= stock.length-1; i++) 
    if(tmp.minVal > stock[i]) 
        tmp.minVal = stock[i];
        tmp.minInd = i;
     else 
        ans.diff = stock[i] - stock[tmp.minInd];
        if(ans.diff > ans.maxDiff)  //Looks like we found a new maxDifference. Lets log the indexes
            ans.maxDiff = ans.diff;
            ans.maxInd = i;
            ans.minInd = tmp.minInd;
            ans.minVal = tmp.minVal;
        
    


document.write('You should buy your stocks on day ' + ans.minInd + ' and sell on day ' + ans.maxInd);

【讨论】:

【参考方案11】:

这是一个实际可行的 C 解决方案:

void bestBuySell() 双倍价格[] = 10.50, 10.0, 3.0, 194.0, 55.39, 2.0, 109.23, 48.29, 81.59, 105.53, 94.45, 191.0, 200.0, 12.24; int arrSize = 14; 双倍 bestBuy = 价格 [0],bestSell = 价格 [1],bestPotentialBuy = 价格 [0]; 双倍潜在利润 = 价格[1] - 价格[0];

for(int i = 1; i < (arrSize-1); i++)

    if(prices[i] < bestBuy)
        bestPotentialBuy = prices[i];            

    if((prices[i+1] - bestPotentialBuy) > potentialProfit)
    
        bestBuy = bestPotentialBuy;
        bestSell = prices[i+1];
        potentialProfit = prices[i+1] - bestPotentialBuy;
    


printf( "bestBuy %f bestSell %f\n", bestBuy, bestSell );

【讨论】:

【参考方案12】:

1.我们不能简单地将值中的最小金额作为“Best Buy”,将最大金额作为“Best Sell”,因为“Sell”必须发生在“Buy”之后。

2.我们不能将记录的最低值视为“最佳买入”,因为随后几天的股票价值可能与记录的最低值的差异可能产生的利润可能低于“记录的利润”。

3.Best Buy 和 Best Sell 被视为一个单一的变量,因为正是这些值之间的正差使利润最大化。

4. 由于过去任何记录的最小值都是潜在的买入候选者,因此必须始终对照记录的最小值和当天的股价检查最大利润条件。因此,我们始终必须跟踪记录的最小值,但是由于原因 2,仅存在记录的最小值并不构成“百思买”。

现在,下面的代码执行 O(n) 次就有意义了。

public class BestStockBuyAndSell 

public static void main(String[] args) 

    double[] stockPrices = 55.39,109.23,48.29,81.59,105.53,94.45,12.24;
    int [] bestBuySellIndex = maxProfit(stockPrices);

    System.out.println("Best Buy At "+stockPrices[bestBuySellIndex[0]]);
    System.out.println("Best Sell At "+stockPrices[bestBuySellIndex[1]]);

    System.out.println("Max Profit = "+(stockPrices[bestBuySellIndex[1]]-stockPrices[bestBuySellIndex[0]]));



public static int[] maxProfit(double[] stockPrices)

    int bestBuy=0;
    int bestSell=0;

    int[] bestCombination =bestBuy,bestSell;
    double recordedMinimum = stockPrices[bestBuy];
    int recordedMinimuIndex = bestBuy;
    double bestProfitSofar = stockPrices[bestSell] - stockPrices[bestBuy];

    for(int i=1;i<stockPrices.length;i++)
    
        if(stockPrices[i] - recordedMinimum > bestProfitSofar)
        

            bestProfitSofar = stockPrices[i] - recordedMinimum;
            bestSell = i;
            bestBuy = recordedMinimuIndex;
        

        if(stockPrices[i] < recordedMinimum)
        
            recordedMinimuIndex = i;
            recordedMinimum = stockPrices[i];
        

    

    bestCombination[0] = bestBuy;
    bestCombination[1] = bestSell;


    return bestCombination;


【讨论】:

【参考方案13】:

我为这个问题想出了以下算法,似乎适用于所有输入。此外,如果 Stock 值不断下降,程序将输出不购买该股票:

  public class GetMaxProfit 
   

  double minValue = -1, maxValue = -1;
  double maxDiff = 0;

  public void getProfit(double [] inputArray)
    int i=0, j=1;
    double newDiff = 0;
    while(j<inputArray.length)
         newDiff = inputArray[j]-inputArray[i];
         if(newDiff > 0)
             if(newDiff > this.maxDiff)
               this.minValue = inputArray[i];
               this.maxValue = inputArray[j];
               this.maxDiff = newDiff;
             
        
        else
            i = j;
        
        j++;
    
 

 public static void main(String[] args) 
    // TODO Auto-generated method stub
    GetMaxProfit obj = new GetMaxProfit();

    obj.getProfit(new double[]55.39, 19.23, 14.29, 11.59, 10.53, 9.45, 1.24);
    if(obj.minValue != -1 && obj.maxValue != -1)
      System.out.println("Buy Value for the input: "+obj.minValue);
      System.out.println("Sell Value for the input: "+obj.maxValue);
      System.out.println("Best profit for the input: "+obj.maxDiff);
            
            else
               System.out.println("Do Not Buy This STOCK!!);

 


你能从中找到什么收获吗?它的时间复杂度是O(N)

【讨论】:

【参考方案14】:

这是我的解决方案,与@Doug T 相同。除了我还在索引中跟踪当天。请提供反馈。

 int prices[] = 4,4,5,6,2,5,1,1;
 //int prices[] = 100, 180, 260, 310, 40, 535, 695;

 int currentBestSellPrice=0;
 int currentBestBuyPrice=0;
 int lowindex=0;
 int highindex=0;
 int low=prices[0];
 int high=prices[0];
 int profit=0;
 int templowindex=0;
 for(int i=0; i< prices.length;i++)
 
     // buy low
     if(prices[i] < low && i+1 < prices.length)
     
         low = prices[i];  
         templowindex=i;
         high=0;
     
     // sell high
     else if(prices[i] > high)
     
         high = prices[i];
         int potentialprofit = (high-low);
         if(potentialprofit > profit)
         
             profit = potentialprofit;
             currentBestSellPrice = high;
             currentBestBuyPrice = low;
             highindex=i;
             lowindex=templowindex;
         
     
 


 System.out.println("Best Buy Price : "+ currentBestBuyPrice + " on day "+ lowindex);
 System.out.println("Best Sell Price : "+ currentBestSellPrice+ " on day "+ highindex );

【讨论】:

【参考方案15】:

F# 解决方案适用于那些对功能感兴趣的人。我不会说它有那么大的不同。

let start, _, profit = 
    [55.39; 109.23; 48.29; 81.59; 81.58; 105.53; 94.45; 12.24 ]
    |> Seq.fold (fun (start,newStart,profit) i -> 
                    let start = defaultArg start i
                    let newStart = defaultArg newStart i
                    let newProfit = i - newStart
                    if profit < newProfit 
                    then  Some newStart, Some newStart,newProfit
                    else if start > i 
                    then Some start, Some i, profit 
                    else Some start,Some newStart,profit) (None,None, 0.0)
printf "Best buy: %f; Best sell: %f" start.Value (start.Value + profit)

输出:

Best buy: 48.290000; Best sell: 105.530000

【讨论】:

【参考方案16】:

这是我在 Ruby 中的解决方案:

values = [55.39, 109.23, 48.29, 81.59, 105.53, 94.45, 12.24]

max_diff = 0
diff = 0
min = values[0]
max = 0

values.each_with_index do |value, index = 1|
  # get an array of the previous values before the current one
  lag_values = values[0..index]

  # get the minimum of those previous values
  min_lag_value = lag_values.min

  # difference between current value and minimum of previous ones
  diff = values[index].to_i - min_lag_value.to_i

  # if current difference is > previous max difference, then set new values for min, max_diff, and max
  if diff > max_diff
    max_diff = diff
    min = min_lag_value
    max = values[index]
  end
end

min # => 48.29
max # => 105.3
max_diff # => 57

干杯

【讨论】:

【参考方案17】:

我得到了 100% 的相同,给你。

public int solution(int[] A) 
      if (A == null || A.length<=1)
            return 0;
        
        int minValue = Math.min(A[0], A[1]);
        int profit = A[1] - A[0];
        for (int i = 2; i < A.length; i++) 
          minValue = Math.min(minValue, A[i]);
          profit = Math.max(A[i] - minValue,profit);
        

        return profit > 0 ? profit : 0;

【讨论】:

【参考方案18】:

我的想法是,对于每个指数i,卖出这只股票的理想指数是什么?这当然是i之后的最大值的索引。这将我们的问题减少到在[1 ... n] 中为每个i 找到索引i 之后的最大元素如果我们可以在O(n) 时间做到这一点,那么我们可以在其中找到最佳选择并报告它。

这样做的一种方法是从数组的末尾开始遍历,维护两个变量,一个保存我们迄今为止遇到的最大元素max_till_now,一个保存我们到目前为止可以获得的最大利润,profit。这只是为了让我们可以一次性完成。我们还可以使用额外的空间,对每个元素i,存储[i + 1 ... n]范围内最大元素的索引,然后找到最大利润。

这是我的python代码:

def buyLowSellHigh(L):
    length = len(L)
    profit = 0
    max_till_now = L[length - 1]
    for i in xrange(length - 2, -1, -1):
        if L[i] > max_till_now: max_till_now = L[i]
        else:
            if max_till_now - L[i] > profit: profit = max_till_now - L[i]
    return profit

【讨论】:

【参考方案19】:

另一个 Ruby 解决方案:

# Here's some examples. Please feel free to give your new test.
values = [55.39, 109.23, 48.29, 81.59, 105.53, 94.45, 12.24]
# values = [5, 6, 4, 7, 9, 8, 8]
# values = [5, 10, 4, 6, 7]
# values = [5, 10, 4, 6, 12]
# values = [1, 2, 3, 4, 5]



# Initialize parameters.
min = values[0]
best_buy_time = values[0]
best_sell_time = values[0]
max_profit = 0



# This solution is based on comparing previous k elements and k+1 one.
# The runtime is O(n) and it only use O(1) auxiliary storage.
values.each_with_index do |value, index = 1|

  # Check value in this turn.
  puts value

  # Check current value is bigger than min or not.
  # If not, we find the new min.
  if value <= min
    min = value

  # If current value is bigger than min and
  # (value - min) is bigger than previous max_profit,
  # set new best_buy_time, best_sell_time & max_profit.
  else
    if value - min >= max_profit
      best_buy_time = min
      best_sell_time = value
      max_profit = value - min
    end

  end

end



# Let's see about the result.
puts "\nbest_buy_time: ", best_buy_time, "\nbest_sell_time: ", best_sell_time, "\nmax_profit: ", max_profit

【讨论】:

【参考方案20】:

这个呢?

min = 100000000
max = 0

for elem in inp:
    if elem < min:
       min = elem
    tempMax = elem-min
    if tempMax > max:
        max = tempMax

print(max)

【讨论】:

【参考方案21】:

javascript 中的解决方案

var stockArr = [13931, 9889, 987, 4, 89, 100];

function getBestTime(sortedArr) 
  var min = 0;
  var buyIndx = 0;
  var saleIndx = 0;
  var maxDiff = 0;
  for (var i = 0; i < stockArr.length; i++) 
    if (stockArr[i] < stockArr[min]) 
      min = i;
    
    var diff = stockArr[i] - stockArr[min];
    if (diff > maxDiff) 
      buy = min;
      sale = i;
      maxDiff = diff;
    
  
  return 
    buy:buy+1,
    sale:sale+1,
    diff:maxDiff
  


console.log(getBestTime(stockArr));

【讨论】:

【参考方案22】:

这是一个 javascript 解决方案..

function getMax(arr)
        //we need more than at least 3 ints to be able to do this
        if(arr.length <= 1) return arr;
        // get the minimum price we can sell at to make a profit
        var min = arr[0];
        //get the first potential maximum profit
        var max = arr[1] - arr[0];

        //while looping through we must get a potential value, 
       //we can then compare that using the math.max using the maximum
      //and the potential prices that we have seen. Once the loop runs the ouput here should be 6!
        for(var i = 1; i < arr.length; ++i)
            var current = arr[i];
            var potential = current - min;

            max = Math.max(max, potential);
            min = Math.min(min, current);
        

        return max;
    

    console.log(getMax([10, 7, 5, 8, 11, 9]));

运行时间为 O(n)

【讨论】:

【参考方案23】:

scala 中的解决方案:

示例:[ 7, 2, 5, 6, 1, 3, 6, 4 ]

保留一个指向最后最低股价(lastStockPrice)的指针,并将其与当前股价进行比较。当您达到当前股票价格

在遍历数组时,请跟踪 currentPrice 和 lastStockPrice 之间的最大差异(利润),因为更新 lastStockPrice 时利润可能会发生变化。

以下 scala 代码在 O(n) 时间内工作,并且占用恒定的空间。

object Solution 
    def maxProfit(prices: Array[Int]): Int = 
        var lastStockPrice = Int.MaxValue
        var maxProfit = 0
        for(currentPrice <- prices)
            if(currentPrice < lastStockPrice)
                lastStockPrice = currentPrice;
            else if(currentPrice - lastStockPrice > maxProfit)
                maxProfit = currentPrice - lastStockPrice;
            
        
        maxProfit
    

【讨论】:

【参考方案24】:

解决此问题的逻辑与使用 Kadane 算法的“最大子数组问题”相同。由于到目前为止还没有任何机构提到过这一点,我认为让每个人都知道这是一件好事。

所有直截了当的解决方案都应该有效,但是如果面试官通过给出不同的价格数组来稍微扭曲问题,例如:对于 1, 7, 4, 11,如果他给出 0, 6, -3 , 7,你最终可能会感到困惑。

这里的逻辑是计算原始数组的差值(maxCur += prices[i] - prices[i-1]),并找到一个连续的子数组给出最大的利润。如果差值低于 0,请将其重置为零。

class Solution:
def maxProfit(self, prices: List[int]) -> int:
    
    _currmax = 0
    _globalMax = 0
    
    for i in range(1,len(prices)):
        
        _currmax = max(_currmax+(prices[i]-prices[i-1]),0)
        _globalMax = max(_globalMax,_currmax)
        
    return _globalMax

【讨论】:

以上是关于在股票价值数组中查找买入/卖出价格以最大化正差的主要内容,如果未能解决你的问题,请参考以下文章

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

买卖股票的最佳时机

121. 买卖股票的最佳时机

maxProfit

maxProfit

数组来算股票的办法