题目:EPI
给一个长度为40的非负整数数组,表示某公司40天的股票价值。找出买卖股票的最大收益及其时间。
提示:买股票的时间必然在卖股票的时间之前。可以在同一天买卖股票。
方法1:分治法。时间复杂度O(n*logn)空间复杂度O(n)。
class stocktrade
{
public:
int buyday;
int sellday;
int profit;
stocktrade(){buyday=-1;sellday=-1;profit=-1;}
};
int minindex(const vector<int> &n,int begin,int end)
{
int index=begin;
for(int i=begin+1;i<=end;i++)
{
if(n[i]<n[index])
index=i;
}
return index;
}
int maxindex(const vector<int> &n,int begin,int end)
{
int index=begin;
for(int i=begin+1;i<=end;i++)
{
if(n[i]>n[index])
index=i;
}
return index;
}
stocktrade MergeArray(const vector<int> &n,int begin,int mid,int end,stocktrade r1,stocktrade r2)
{
if(r2.buyday<0)
return r1;
stocktrade res;
int biggest=max(r1.profit,r2.profit);
int buyday=minindex(n,begin,mid);
int sellday=maxindex(n,mid+1,end);
if(n[sellday]-n[buyday]>biggest)
{
res.buyday=buyday;
res.sellday=sellday;
res.profit=n[sellday]-n[buyday];
return res;
}
else
{
if(r1.profit>r2.profit)
return r1;
else
return r2;
}
}
stocktrade trade(const vector<int> &n,int begin,int end)
{
stocktrade res;
if(begin>=n.size() || end<begin)
return res;
if(begin==end)
{
res.buyday=begin;
res.sellday=begin;
res.profit=0;
}
else
{
int mid=(begin+end)/2;
stocktrade r1=trade(n,begin,mid);
stocktrade r2=trade(n,mid+1,end);
res=MergeArray(n,begin,mid,end,r1,r2);
}
return res;
}
stocktrade buyandsell2(const vector<int> &n)
{
stocktrade res;
if(n.empty())
return res;
int mid=(n.size()-1)/2;
stocktrade r1=trade(n,0,mid);
stocktrade r2=trade(n,mid+1,n.size()-1);
res=MergeArray(n,0,mid,n.size()-1,r1,r2);
return res;
}
方法2:遍历一次数组,记录当前时间点之前股票价格的最小值,对比最大收益。时间复杂度O(n)空间复杂度O(1)。
class stocktrade
{
public:
int buyday;
int sellday;
int profit;
stocktrade(){buyday=-1;sellday=-1;profit=-1;}
};
stocktrade buyandsell(vector<int> n)
{
stocktrade res;
if(n.empty())
return res;
res.buyday=0;
res.sellday=0;
int minday=0;
int biggest=0;
for(int i=1;i<n.size();i++)
{
if( (n[i]-n[minday])>biggest)
{
res.buyday=minday;
res.sellday=i;
biggest=n[i]-n[minday];
}
if(n[i]<n[minday])
minday=i;
}
res.profit=biggest;
return res;
}