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).
分析:这一题约束最多只能买卖两次股票,并且手上最多也只能持有一支股票。因为不能连续买入两次股票,所以买卖两次肯定分布在前后两个不同的区间。设p(i) = 区间[0,1,2...i]的最大利润 + 区间[i,i+1,....n-1]的最大利润(式子中两个区间内分别只能有一次买卖,这就是第一道题的问题),那么本题的最大利润 = max{p[0],p[1],p[2],...,p[n-1]}。根据第一题的算法2,我们可以求区间[0,1,2...i]的最大利润;同理可以从后往前扫描数组求区间[i,i+1,....n-1]的最大利润,其递归式如下:
dp[i-1] = max{dp[i], maxprices - prices[i-1]} ,maxprices是区间[i,i+1,...,n-1]内的最高价格。
因此两趟扫描数组就可以解决这个问题,代码如下:
class Solution {
public:
int maxProfit(vector<int> &prices) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
const int len = prices.size();
if(len <= 1)return 0;
int maxFromHead[len];
maxFromHead[0] = 0;
int minprice = prices[0], maxprofit = 0;
for(int i = 1; i < len; i++)
{
minprice = min(prices[i-1], minprice);
if(maxprofit < prices[i] - minprice)
maxprofit = prices[i] - minprice;
maxFromHead[i] = maxprofit;
}
int maxprice = prices[len - 1];
int res = maxFromHead[len-1];
maxprofit = 0;
for(int i = len-2; i >=0; i--)
{
maxprice = max(maxprice, prices[i+1]);
if(maxprofit < maxprice - prices[i])
maxprofit = maxprice - prices[i];
if(res < maxFromHead[i] + maxprofit)
res = maxFromHead[i] + maxprofit;
}
return res;
}
};
9.15号更新
------------------
注意:算法需要两次扫描,一次从前向后扫,枚举的是是否在当前元素抛出,一次是从后向前扫,枚举的是是否在当前元素买入!!!
class Solution { public: int maxProfit(vector<int> &prices) { if(prices.empty()) return 0; int n = prices.size(); vector<int> leftProfit(n,0); int maxLeftProfit = 0, minPrice = prices[0]; for(int i=1; i<n; i++) { if(prices[i]<minPrice) minPrice = prices[i]; else maxLeftProfit = max(maxLeftProfit, prices[i]-minPrice); leftProfit[i] = maxLeftProfit; } int ret = leftProfit[n-1]; //注意对ret的初始化 int maxRightProfit = 0, maxPrice = prices[n-1]; for(int i=n-2; i>=0; i--) { if(prices[i]>maxPrice) maxPrice = prices[i]; else maxRightProfit = max(maxRightProfit, maxPrice-prices[i]); ret = max(ret, maxRightProfit + leftProfit[i]); } return ret; } };