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).
1.我的解答 时间复杂度为O(n^3) 超时了,思路再加强一下
算出第i天买进第j天卖出的收益,及第i天买进时最大的收益,第j天卖出的最大收益
这两笔交易相加找最大值就行
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
if(n <= 1) return 0;
vector<vector<int>>buytosell(n, vector<int>(n,0));
vector<int>sell_best(n,0);//哪天卖出收益最大 sell_best[i] 表示第i天卖出的收益最大
vector<int>buy_best(n,0); //哪天买进收益最大 buy_best[i] 表示第i天买进的收益最大
for(int i = 0; i < n; i++){
for(int j = i+1; j < n; j++){
buytosell[i][j] = prices[j] - prices[i];
}
}
int buymax = 0, sellmax = 0, maxn = 0;
for(int i = 0; i < n; i++){
buymax = 0;
for(int j = 0; j < n; j++){
buymax = max(buymax, buytosell[i][j]);
}
buy_best[i] = buymax;
maxn = max(maxn, buymax);
}
for(int i = 0; i < n; i++){
sellmax = 0;
for(int j = 0; j < n; j++){
sellmax = max(sellmax, buytosell[j][i]);
}
sell_best[i] = sellmax;
maxn = max(maxn, sellmax);
}
for(int i = 0; i < n; i ++){ //假如给定范围[i,j],即第i天买进第j天卖出,这算一笔交易的话,则k表示第k天时买进的最大收益
for(int j = i+1; j < n; j++){
for(int k = j+1; k < n; k++){
maxn = max(maxn, buy_best[k] + buytosell[i][j]); //这就是找[i,j]这一笔交易+第k天卖出的收益两者的最大值
}
}
}
return maxn;
}
};
2.对以上的思路再加强一下
记下从第一天到第i天为止的最大收益和第j天开始到最后的最大收益
那么以i作为切分点,则f[i]+f[j]就是两笔交易,取最大值即可。
---------------------
以下是别人的题解,我觉得真心说得不错
题意:用一个数组表示股票每天的价格,数组的第i个数表示股票在第i天的价格。最多交易两次,手上最多只能持有一支股票,求最大收益。
分析:动态规划法。以第i天为分界线,计算第i天之前进行一次交易的最大收益preProfit[i],和第i天之后进行一次交易的最大收益postProfit[i],最后遍历一遍,max{preProfit[i] + postProfit[i]} (0≤i≤n-1)就是最大收益。第i天之前和第i天之后进行一次的最大收益求法同Best Time to Buy and Sell Stock I。
下面是我的实现的代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
if(n <= 1) return 0;
vector<int>first(n,0); //到第i天为止,前i天的最大收益
vector<int>second(n,0);//从第i天开始,后边的最大的收益
int minprice = prices[0];
for(int i = 1; i < n; i++){
minprice = min(minprice, prices[i]);
first[i] = max(first[i-1], prices[i] - minprice);
}
int maxprice = prices[n-1];
for(int j = n - 2; j >= 0; j--){
maxprice = max(maxprice, prices[j]);
second[j] = max(second[j+1], maxprice - prices[j]);
}
int maxn = 0;
for(int i = 0; i < n; i++){
maxn = max(maxn, first[i] + second[i]);
}
return maxn;
}
};