您的位置:首页 > 其它

Leetcode Best Time to Buy and Sell Stock IV(最大子段和)

2016-01-12 17:13 330 查看
朴素的O(n^2)过不了,这里借鉴前人的思想,总结一下。

主要利用栈维护对后面产生影响的字段,然后利用贪心的思想逐步合并。

首先,找到每一对最低点(vx),最高点(px);

其次,合并当前(vx, px) 与栈内的点对(top_vx, top_px),分两种情况

1、若top_vx  >= vx,考虑到vx处在更低点,(top_vx, top_px)对后面的点对不会有影响,则对(top_vx, top_px)计算价值并出栈;

2、若top_px <= px(ps:此时top_vx  < vx), 

      a、若最优解只包含两对点的其中一对,显然可以合并两对点为(top_vx, px)最优;

      b、若最优解中包含两对点,则可将两对点转化成(top_vx, px), (vx, top_ px), 其中(vx, top_ px)对后面的点对不会有影响,则对(vx, top_ px)对计算价值并出栈,同时更新(vx, px)->(top_vx, px);

最后,将栈内的点对全部计算价值(显然栈内的点对都不必合并)。

class Solution {
stack< pair<int, int> > waiting;
vector<int> profits;
public:
int maxProfit(int k, vector<int>& pr) {
int len = pr.size();
if(len < 2 || k < 1) return 0;
while(!waiting.empty()) waiting.pop();
profits.clear();

int posv, posp = -1;
while(true)
{
for(posv = posp + 1; (posv + 1) < len && pr[posv] >= pr[posv + 1]; posv++);
for(posp = posv + 1; (posp + 1) < len && pr[posp] <= pr[posp + 1]; posp++);
if(posp >= len) break;

for(; !waiting.empty() && pr[waiting.top().first] >= pr[posv]; waiting.pop())
{
profits.push_back(pr[waiting.top().second] - pr[waiting.top().first]);
}
for(; !waiting.empty() && pr[waiting.top().second] <= pr[posp]; waiting.pop())
{
profits.push_back(pr[waiting.top().second] - pr[posv]);
posv = waiting.top().first;
}
waiting.push(make_pair(posv, posp));
}

for(; !waiting.empty(); waiting.pop())
{
profits.push_back(pr[waiting.top().second] - pr[waiting.top().first]);
}

int ans = 0;
if(k >= profits.size())
{
ans = accumulate(profits.begin(), profits.end(), 0);
}
else
{
nth_element(profits.begin(), profits.begin() + k - 1, profits.end(), greater<int>());
ans = accumulate(profits.begin(), profits.begin() + k, 0);
}

return ans;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: