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);
最后,将栈内的点对全部计算价值(显然栈内的点对都不必合并)。
主要利用栈维护对后面产生影响的字段,然后利用贪心的思想逐步合并。
首先,找到每一对最低点(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; } };
相关文章推荐
- 获取视频的第一帧缩略图(本地视频、网络视频)
- 阿里云服务器部署git 服务器
- listview设置数据为空时显示数据
- 使用gdal ogr创建shapefile文件(c++)
- 判断字符串是否包含特殊字符正则
- CDI进阶第十步 查找上下文
- java中Keytool的使用总结
- 使用触发器订单序列号生成
- 46. Permutations && 47. Permutations II
- 搜狗技术团队为何从oracle转mysql 【转】
- 看雪论坛大神的破解游戏反调试思路
- 侧边栏 SlidingMenu
- 选择排序
- c++编程四舍五入算法
- 快速掌握Lua 5.3 —— 让我们开始吧
- 30 天学习 30 种新技术
- docker资源限制
- IntentFilter,PendingIntent
- 软件测试报告写作实战案例
- 解决:C语言调用pcap库出现unknown types error