Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在一天内买卖股票_Algorithm - Fatal编程技术网

Algorithm 在一天内买卖股票

Algorithm 在一天内买卖股票,algorithm,Algorithm,我在一次采访中被问到这个问题: 假设您有一个数组,其第i个元素是第一天给定股票的价格。 如果你只被允许买入一股股票,卖出一股股票,那么设计一个算法来寻找买入和卖出的最佳时机。我能够给出一个O(n)算法 面试官问了我一个后续问题,“买一,卖一”,然后“买一,卖一”,这意味着一天有两次交易,利润最大化。我能够给出一个O(n^2)算法。但是采访者说这是可以改进的。有O(n)算法吗 面试官说你不能同时买两份股票。你必须买一个卖掉它,然后在另一个时间买一个,然后卖掉它。原始问题中给出的O(n)解为原始数

我在一次采访中被问到这个问题:

假设您有一个数组,其第i个元素是第一天给定股票的价格。 如果你只被允许买入一股股票,卖出一股股票,那么设计一个算法来寻找买入和卖出的最佳时机。我能够给出一个O(n)算法

面试官问了我一个后续问题,“买一,卖一”,然后“买一,卖一”,这意味着一天有两次交易,利润最大化。我能够给出一个O(n^2)算法。但是采访者说这是可以改进的。有O(n)算法吗

面试官说你不能同时买两份股票。你必须买一个卖掉它,然后在另一个时间买一个,然后卖掉它。

原始问题中给出的O(n)解为原始数组的每个前缀提供了最佳的“买一个然后卖掉一个”答案。该算法也可以简单地修改以应对“倒退”情况;i、 e.一个“先卖一个,然后买一个”,你从阵列中向后工作;这相当于数组的每个后缀都有“买一个然后卖一个”的答案

现在,在“买,卖,买,卖”的情况下,我们有一些点(在第一次卖出之后)在我们的数组中的某个地方,比如b。对于该断点,最佳解决方案是0..b的最佳前缀解决方案和b+1..n的最佳后缀解决方案。最好的“买、卖、买、卖”整体是这些最佳解决方案的最佳选择

因此,要解决O(n)中的“买、卖、买、卖”,您可以解决O(n)中的前缀,O(n)中的后缀,然后为每个断点计算最佳值-So nO(1)。这是一个使用O(n)空间的O(n)算法。

原始问题中给出的O(n)解为原始数组的每个前缀提供了最佳的“买一然后卖一”答案。该算法也可以简单地修改以应对“倒退”情况;i、 e.一个“先卖一个,然后买一个”,你从阵列中向后工作;这相当于数组的每个后缀都有“买一个然后卖一个”的答案

现在,在“买,卖,买,卖”的情况下,我们有一些点(在第一次卖出之后)在我们的数组中的某个地方,比如b。对于该断点,最佳解决方案是0..b的最佳前缀解决方案和b+1..n的最佳后缀解决方案。最好的“买、卖、买、卖”整体是这些最佳解决方案的最佳选择


因此,要解决O(n)中的“买、卖、买、卖”,您可以解决O(n)中的前缀,O(n)中的后缀,然后为每个断点计算最佳值-So nO(1)。这是一个使用O(n)空间的O(n)算法。

它可以优化为只有一个for循环,但其思想基本相同:

int maxProfit(vector<int> &prices) {        
    if (prices.empty()) return 0;        

    int n = prices.size();
    int lHolding = prices[0], rHolding = prices[n-1];
    int lMax = 0, rMax = 0;        

    vector<int> profit(n);

    for (int i = 1; i < n; i++) {            
        if (prices[i] > lHolding) {
            lMax = max(lMax, prices[i] - lHolding);
        } else {
            lHolding = prices[i];
        }

        profit[i] += lMax;

        int right = n - 1 - i;

        if (rHolding > prices[right]) {
            rMax = max(rMax, rHolding - prices[right]);
        } else {
            rHolding = prices[right];
        }

        profit[right] += rMax;            
    }

    return *max_element(profit.begin(), profit.end());        
}
int最大利润(向量和价格){
if(prices.empty())返回0;
int n=prices.size();
int lHolding=价格[0],rHolding=价格[n-1];
int-lMax=0,rMax=0;
向量利润(n);
对于(inti=1;iL控股){
lMax=max(lMax,价格[i]-lHolding);
}否则{
lHolding=价格[i];
}
利润[i]+=lMax;
int right=n-1-i;
如果(rHolding>价格[右]){
rMax=最大值(rMax,rHolding-价格[右]);
}否则{
rHolding=价格[右];
}
利润[权利]+=rMax;
}
return*max_元素(profit.begin(),profit.end());
}

它可以优化为只有一个for循环,但其思想基本相同:

int maxProfit(vector<int> &prices) {        
    if (prices.empty()) return 0;        

    int n = prices.size();
    int lHolding = prices[0], rHolding = prices[n-1];
    int lMax = 0, rMax = 0;        

    vector<int> profit(n);

    for (int i = 1; i < n; i++) {            
        if (prices[i] > lHolding) {
            lMax = max(lMax, prices[i] - lHolding);
        } else {
            lHolding = prices[i];
        }

        profit[i] += lMax;

        int right = n - 1 - i;

        if (rHolding > prices[right]) {
            rMax = max(rMax, rHolding - prices[right]);
        } else {
            rHolding = prices[right];
        }

        profit[right] += rMax;            
    }

    return *max_element(profit.begin(), profit.end());        
}
int最大利润(向量和价格){
if(prices.empty())返回0;
int n=prices.size();
int lHolding=价格[0],rHolding=价格[n-1];
int-lMax=0,rMax=0;
向量利润(n);
对于(inti=1;iL控股){
lMax=max(lMax,价格[i]-lHolding);
}否则{
lHolding=价格[i];
}
利润[i]+=lMax;
int right=n-1-i;
如果(rHolding>价格[右]){
rMax=最大值(rMax,rHolding-价格[右]);
}否则{
rHolding=价格[右];
}
利润[权利]+=rMax;
}
return*max_元素(profit.begin(),profit.end());
}

我比赛迟到了,但就在这里。首先,borrible给出的解决方案不太清楚,因为有人可以实现它并得到O(n^2)。这仅仅是通过循环通过b,对于每个b,计算前缀和后缀,它们都是O(n),所以它们一起是O(n)*(n),其中(n)来自b=1…n。这意味着结果是O(n^2)

为了实现该描述,使其以O(n)运行,需要认识到前缀和后缀是独立的,可以像Daniel实现的那样单独运行

这个解决方案的问题是它需要一个O(n)空间。假设您的库存跟踪是1千兆点(例如,如果您要迭代2年的数据,这是很常见的),那么您将占用大量内存

如果我是面试官,下一个合乎逻辑的问题是:是否有可能取消记忆要求

让我试一试。大部分只是计算基础数学

我们有一个数组[0…n-1]


在原来的问题中,我们想找到r,s,其中0我迟到了,但在这里。首先,borrible给出的解决方案不太清楚,因为有人可以实现它并得到O(n^2)。这仅仅是通过循环通过b,对于每个b,计算前缀和后缀,它们都是O(n),所以它们一起是O(n)*(n),其中(n)来自b=1…n。这意味着结果是O(n^2)

要实现该描述,使其在O(n)中运行,需要重新编码