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.
思路:
找寻一个点j,将原来的price[0..n-1]分割为price[0..j]和price[j..n-1],分别求两段的最大profit。对于此思路O(n^2)复杂度的做法比较好想。
但是,在此过程中,有很多重复计算的内容,如何去除重复计算,成了一个问题。对于点j+1,求price[0..j+1]的最大profit时,很多工作是重复的,在求price[0..j]的最大profit中已经做过了。
优化:
定义两个数组leftMax[n],记录0-i的最大profit
rightMax[n],记录i-n的最大profit。
这样就省略了很多重复的计算。
int maxProfit(vector<int> &prices){
int n = prices.size();
if(n<=1) return 0;
int profit=0;
int leftMax[n],rightMax[n];
memset(leftMax, 0, sizeof(int) * n);
memset(rightMax, 0, sizeof(int) * n);
//找到0-i的最大profit
int minpro=prices[0];
for(int i=1; i<n; i++){
minpro = min(minpro, prices[i-1]);
if(leftMax[i-1]<(prices[i]-minpro)){
leftMax[i] = prices[i]-minpro;
}
else{
leftMax[i] = leftMax[i-1];
}
}
//找到i-n的最大profit
int maxpro=prices[n-1];
for(int i=n-2; i>=0; i--){
maxpro = max(maxpro,prices[i+1]);
if(rightMax[i+1] < (maxpro-prices[i]))
{
rightMax[i] = maxpro-prices[i];
}
else{
rightMax[i] = rightMax[i+1];
}
}
for(int i=0; i<n; i++){
if(profit<leftMax[i]+rightMax[i]){
profit = leftMax[i]+rightMax[i];
}
}
return profit;
}