题目:

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete at most two transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

代码:

class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.empty()) return ;
const int len = prices.size();
vector<int> l(len,),r(len,);
// from left to right
l[] = ;
int l_min = prices[];
for ( int i = ; i < l.size(); ++i )
{
l_min = std::min(l_min, prices[i]);
l[i] = std::max(l[i-], prices[i]-l_min);
}
// from right to left
r[len-] = ;
int r_max = prices[len-];
for ( int i = len-; i >= ; --i )
{
r_max = std::max(r_max, prices[i]);
r[i] = std::max(r[i-], r_max-prices[i]);
}
// travseral the best two times
int max_profit = ;
for ( int i = ; i < prices.size(); ++i )
{
max_profit = std::max(max_profit, l[i]+r[i]);
}
return max_profit;
}
};

tips:

此题说最多交易两次,求最大获利。

直觉的想法就是,把整个时间段分割成两部分( 共有prices.size()种分类方法 );分好后分别求两部分各自的最大值;这种算法是O(n²)时间复杂度的。

模仿之前求过的largest rectangle in histogram这道题的思路,能否利用dp思想,把算过的中间结果都存起来,把时间复杂度降低到O(n)。

想到这个思路就比较明确了:

1. 从左向右走一遍,l[i]存放0~i最多交易1次获利最大的值

2. 从右向左走一遍,r[i]存放i~prices.size()-1最多交易一次获利的最大值

3. 遍历数组l和数组r,通过遍历每种分割情况下的最大获利,并最终获得最终的最大获利值。

这里还有个细节可能会产生疑义:如果以第i天作为分割点,那么这第i天是算到前半截还是后半截呢?

这里分两种情况:

1. 如果“前半截的最大利润”和“后半截的最大利润”只有一截涉及到了第i天,显然l[i]+r[i]这个算法是没问题的

2. 如果“前”、“后”两截都涉及到了第i天呢?这时候有两种理解方法:

  2.1 前后交易两次:前半截的某一天买入,第i天卖了,挣一笔;第i天卖完又买入了,到后面的某一天又卖了,挣第二笔。两笔加起来最大。

  2.2 前后交易一次:前半截的某一天买入,第i天虽然卖了获利最大,但是不卖,留着;等到后面的某一天发现获利最大,直接挣一笔最大的,同样获利最大。

因此,无论按照哪种理解方法,l[i]+r[i]都是合理的,不会因为第i天作为分割点而产生影响。

=====================================================

第二次过这道题,思路上有个地方没有理清(红字),在当天可以选择交易或者不交易,如果不交易那么等于左边(或右边)相邻元素的值。

class Solution {
public:
int maxProfit(vector<int>& prices) {
if ( prices.empty() ) return ;
vector<int> l(prices.size(), );
vector<int> r(prices.size(), );
// l
int minPrices = prices[];
for ( int i=; i<prices.size(); ++i )
{
minPrices = min(prices[i], minPrices);
l[i] = max(l[i-1], prices[i]-minPrices);
}
// r
int maxPrices = prices[prices.size()-];
for ( int i=prices.size()-; i>=; --i )
{
maxPrices = max(maxPrices, prices[i]);
r[i] = max(r[i+1], maxPrices - prices[i]);
}
// l to r
int ret = ;
for ( int i=; i<prices.size(); ++i )
{
ret = max(ret, l[i]+r[i]);
}
return ret;
}
};

【Best Time to Buy and Sell Stock III 】cpp的更多相关文章

  1. 【Best Time to Buy and Sell Stock II】cpp

    题目: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...

  2. leetcode 【 Best Time to Buy and Sell Stock III 】python 实现

    题目: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...

  3. leetcode 【 Best Time to Buy and Sell Stock II 】python 实现

    题目: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...

  4. 【LeetCode-面试算法经典-Java实现】【121-Best Time to Buy and Sell Stock(最佳买卖股票的时间)】

    [121-Best Time to Buy and Sell Stock(最佳买卖股票的时间)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Say you have ...

  5. 【leetcode】Best Time to Buy and Sell Stock III

    Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the price of ...

  6. 【leetcode】123. Best Time to Buy and Sell Stock III

    @requires_authorization @author johnsondu @create_time 2015.7.22 19:04 @url [Best Time to Buy and Se ...

  7. 【刷题-LeetCode】123 Best Time to Buy and Sell Stock III

    Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the price of ...

  8. 27. Best Time to Buy and Sell Stock && Best Time to Buy and Sell Stock II && Best Time to Buy and Sell Stock III

    Best Time to Buy and Sell Stock (onlineJudge: https://oj.leetcode.com/problems/best-time-to-buy-and- ...

  9. LeetCode 笔记23 Best Time to Buy and Sell Stock III

    Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the price of ...

随机推荐

  1. Android 应用开机自启和无需权限开启悬浮框

    开机自启主要自定义广播接收类,且需要在清单文件中注册,不要在代码中动态注册. <uses-permission android:name="android.permission.REC ...

  2. cms-最近更新

    在这一讲中有几个很重要的地方需要注意: 1.在查询帖子的时候需要把帖子类型id带到帖子类型表中把类型查询出来 2.在字帖子查询语句中用limt限制查询那个阶段的帖子 3.在界面显示的时候需要用到字符串 ...

  3. LeetCode OJ 3Sum 3个整数之和

    题意:给一个vector<int>容器,要求每当找到3个元素之和为0时就将这3个数按大小顺序记下来,用一个二维vector返回.也就是vector< vector<int> ...

  4. Python开发第三篇

    函数 一.函数参数传值 形参:函数在定义的时候给定的参数 实参:函数在运行时赋给的参数: def func(i):#i为定义时的参数,为形参 pass func(name)#name为运行时的参数,为 ...

  5. iOS解析新浪微博的@##以及URL链接并展示

    最近在做一个跟微博相关的应用.其中涉及到了对微博中@.##以及URL链接的解析与展示.分享一下个人处理的方式,希望对需要的人有所帮助. 最终的展现效果: 首先,第一步是你得从纯文本中找到它们.毫无疑问 ...

  6. ORACLE的raw属性

    网上说RAW类型在网络数据传送的时候可以避免字节的字符集转换,在mssql中使用的GUID类型在oracle中对应的也是raw类型(一般是raw(16)),如果此时使用连接查询将raw类型的字段和va ...

  7. Android(java)学习笔记95:Android运行时异常"Binary XML file line # : Error inflating class"

    在原生Android下编译APK,编译没有问题,但是在运行的时候经常出现如标题所描述的异常:"Binary XML file line # : Error inflating class&q ...

  8. C++之RAII惯用法

    http://blog.csdn.net/hunter8777/article/details/6327704 C++中的RAII全称是“Resource acquisition is initial ...

  9. windows平台下MongoDB安装和环境搭建

    下载安装包或者压缩包 添加db存储和日志存储文件夹 添加服务.配置环境变量.启动Mongo 本例:安装路径:D:Program Files/MongoDB 配置文件的路径:D:MongoDB 一.安装 ...

  10. Springboot端口设置

    application.properties 加入 server.port=80