题目大意是:给一个股票价格数组,你最多能买卖两次,问最大收益
比如输入 2 4 则最大收益是2
输入 1 20 2 30 则最大收益是19+28
之前网上有一段DP的代码时间复杂度是o(n)这是满足时间要求的,但空间复杂度是o(n),其实DP都是用空间换时间的方法。有兴趣可以上网搜一搜,自己写也不麻烦
现在和大家说说时间复杂度为o(n),空间复杂度为o(1)的一个办法。
大家还记得求买卖一次的最大收益的方法吧?
我们先求该数组中买卖一次的最大收益max0. 并且记下买和卖时的数组下标或迭代器指针。就当买时的下标为a卖时为b
然后我们求下标0到a-1的子数组中买卖一次的最大收益max1
和下标b+1到end()的子数组中买卖一次的最大收益max2
以及a+1到b-1的子数字中买卖一次的最大亏损(得为负数)取正后为max3
最后我们要的结果就是max0 + max(max1,max2,max3)
呵呵方法其实很简单,这里就不提供数学证明了,如果有疑问可以讨论,如下给我我在leetcode上的C++代码实现,程序写的拙劣,希望大家给出批评指导意见,无论是对算法的改进,还是从程序设计或软件工程角度的想法意见。希望大家不吝赐教!!
class Solution {
public:
vector<int>::iterator right,left;
int find(vector<int> &prices,vector<int>::iterator lef,vector<int>::iterator rig)
{
int min=1000000000,maxs=0;
vector<int>::iterator lefbuf;
while(lef<rig)
{
if(*lef<min)
{
min=*lef;
lefbuf=lef;
};
if(*lef>min && (*lef-min)>maxs)
{
maxs=*lef-min;
left=lefbuf;
right=lef;
};
lef++;
};
return maxs;
};
int rfind(vector<int> &prices,vector<int>::iterator lef,vector<int>::iterator rig)
{
int min=1000000000,maxs=0;
while(lef<rig)
{
if(*rig<min)
{
min=*rig;
};
if(*rig>min && (*rig-min)>maxs)
{
maxs=*rig-min;
};
rig--;
};
return maxs;
}
int maxProfit(vector<int> &prices) {
int max,max1,max2,max3;
vector<int>::iterator bufright,bufleft;
max1=max2=max3=0;
max=find(prices,prices.begin(),prices.end());
if(max==0)return 0;
bufright=right;bufleft=left;
max1=find(prices,prices.begin(),bufleft);
max2=rfind(prices,bufleft,bufright-1);
max3=find(prices,bufright+1,prices.end());
if(max1>max2)max2=max1;
if(max2>max3)max3=max2;
return max+max3;
}
};