首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >线性复杂度的分治算法?

线性复杂度的分治算法?
EN

Stack Overflow用户
提问于 2015-02-23 03:54:06
回答 3查看 416关注 0票数 1

我们有一组表示随时间变化的价格的数字。例如,我们有10,4,6,8,2,5,3,9,1。我们想知道什么时候是最好的买入和卖出时间,以实现利润最大化。在这种情况下,我们以time4 =2的价格买入,以time7 =9的价格卖出,利润为9-2= 7。

在数学上,我们正在寻找a和b,其中a <= b和timeb - timea是最大的。

使用divide and conquer实现复杂度为O(nlogn)的算法有点微不足道。我一直在寻找一种最坏情况为O(n)的算法,但一直没有成功。任何帮助都将不胜感激。

EN

回答 3

Stack Overflow用户

发布于 2015-02-23 03:59:37

这里不需要分而治之。从最早的价格到最新的价格遍历数组,并在每个步骤中将当前价格与到目前为止找到的最低价格进行比较。

票数 2
EN

Stack Overflow用户

发布于 2015-02-23 04:03:14

10,4,6,8,2,5,3,9,1。

将上面的列表转换为O(n)中的梯度。-6,2,2,-6,3,-2,6,-8

应用卡达内算法寻找最大子数组O(n):http://en.wikipedia.org/wiki/Maximum_subarray_problem

^修改以存储起始位置和结束位置。

使用kadane算法中的起始位置来找到原始数组的起始和结束位置。

票数 0
EN

Stack Overflow用户

发布于 2015-02-23 04:13:25

如果我们作为第一步预先计算一个向量,该向量指定索引i的每个范围(0,i-1)的最低价格,然后计算如果我们在索引i卖出,我们可以在O(n)时间内计算出的最大价格:

代码:

代码语言:javascript
运行
复制
#include <iostream>
#include <algorithm>
#include <limits>
#include <vector>
using namespace std;

int main() {
    vector<int> prices{10, 4, 6, 8, 2, 5, 3, 9, 1};
    // sell at time [i] requires buy at minimum in range [0,i-1]
    // create vector of index at minimum for each range
    int currentMinimumIndex = 0;
    vector<int> minimums{0};
    for(size_t i = 1; i < prices.size(); ++i)
    {
        if (prices[i] < prices[currentMinimumIndex])
        {
            minimums.emplace_back(i);
            currentMinimumIndex = i;
        }
        else
            minimums.emplace_back(currentMinimumIndex);
    } // O(n)

    // at this point we have a lookup table for minimum in every range

    // attempt to maximize amount we can get if we sell at time i buy buying at minimum for (0,i-1)
    vector<int> maxSales{std::numeric_limits<int>::min()};
    for(size_t i=1;i<prices.size();++i)
    {
        maxSales.emplace_back(prices[i] - prices[minimums[i]]);
    } // O(n)

    // find maximum element
    auto maxSum = std::max_element(std::begin(maxSales), std::end(maxSales)); // O(n)
    auto sellAt = std::distance(std::begin(maxSales), maxSum);
    auto buyAt = minimums[sellAt];
    std::cout << "Maximum profit is " << *maxSum << std::endl;
    std::cout << "If we buy at index " << buyAt << " (price: " << prices[buyAt] << ")"
    << " and sell at " << sellAt << " (price: " << prices[sellAt] << ")" << std::endl;

    return 0;
}

输出:

如果我们以指数4(价格: 2)买入,以7(价格: 9)出售,

最大利润为7。

Live Example

编辑:这是一种动态编程风格的方法,我现在意识到它有点过头了。如果我们做hugomg said,那么我们将简单地从左到右迭代,存储到目前为止找到的最小值。在每个新的指数i,我们执行减法,看看我们是否有一个新的最大价格。时间是线性的,空间是恒定的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28662502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档