leetcode 714. Best Time to Buy and Sell Stock with Transaction Fee
(未完待续)
一开始的想法:遍历,低买高卖,考虑手续费,所以价差不超过手续费不卖,先跌后涨但跌幅不超过手续费不卖,示例正确但Wrong Answer。
class Solution {
public:
int maxProfit(vector<int>& prices, int fee)
{
int len=prices.size();
if(len==0)
return 0;
if(len==1)
return 0;
int INF=1e6;
int profit=0;
int left_i=-1;
// int left_val=-INF;
int prev_val=prices[0];
int tmp_val=-1;
// find first ascend point
for(int i=1;i<len;++i)
{
tmp_val=prices[i];
if(tmp_val>prev_val)
{
//first ascend point
left_i=i-1;
break;
}
prev_val=tmp_val;
}
if(left_i==-1)
{
// descending list
return 0;
}
// cout<<"first left_i: "<<left_i<<endl;
int drop_sum=-1;
int turn_i=-1;
int i=left_i+1;
prev_val=prices[left_i];
while(i<len)
{
tmp_val=prices[i];
// cout<<"i: "<<i<<", prev_val: "<<prev_val<<", tmp_val: "<<tmp_val<<endl;
if(left_i==-1)
{
if(tmp_val<=prev_val)
{
++i;
prev_val=tmp_val;
continue;
}
left_i=i-1;
++i;
prev_val=tmp_val;
continue;
}
// if(prev_val-tmp_val>fee)
// {
// // sell
// profit+=(prev_val-left_val);
// left_i=i;
// left_val=tmp_val;
// continue;
// }
if(prev_val==tmp_val)
{
++i;
}
else if(prev_val<tmp_val)
{
if(drop_sum==-1)
{
++i;
prev_val=tmp_val;
continue;
}
drop_sum-=(tmp_val-prev_val);
if(drop_sum<=0)
{
turn_i=-1;
drop_sum=-1;
}
++i;
prev_val=tmp_val;
}
else if(prev_val>tmp_val)
{
if(drop_sum==-1)
{
turn_i=i-1;
drop_sum=prev_val-tmp_val;
// cout<<"update drop_sum from -1 to "<<drop_sum<<endl;
}
else
{
drop_sum+=(prev_val-tmp_val);
}
if(drop_sum>fee)
{
// probable sell
int tmp_profit=prices[turn_i]-prices[left_i]-fee;
if(tmp_profit>0)
{
// cout<<"sell between left_i and turn_i"<<endl;
// cout<<"left_i: "<<left_i<<", turn_i: "<<turn_i<<endl;
// cout<<"tmp_profit: "<<tmp_profit<<endl;
profit+=tmp_profit;
}
left_i=-1;
turn_i=-1;
drop_sum=-1;
}
++i;
prev_val=tmp_val;
}
}
if(left_i==-1)
return profit;
if(turn_i==-1)
{
int tmp_profit=prices[len-1]-prices[left_i]-fee;
if(tmp_profit>0)
profit+=tmp_profit;
}
else
{
int tmp_profit=prices[turn_i]-prices[left_i]-fee;
if(tmp_profit>0)
profit+=tmp_profit;
}
return profit;
}
};
题解:认为买入的时候给手续费,每个时间点有两种状态:持有或不持有,初始不持有股票,账户余额为0,最终不持有股票,求最大的账户余额。递推,当前持有状态的最大余额和不持有状态的最大余额。
class Solution {
public:
int maxProfit(vector<int>& prices, int fee)
{
if(prices.size()==0)
return 0;
int balance_hold=-1e8;
int balance_not_hold=0;
int prev_balance_hold;
int prev_balance_not_hold;
for(vector<int>::iterator it=prices.begin();it!=prices.end();++it)
{
int price=*it;
prev_balance_hold=balance_hold;
prev_balance_not_hold=balance_not_hold;
balance_hold=max(prev_balance_hold,prev_balance_not_hold-price-fee);
balance_not_hold=max(prev_balance_not_hold,prev_balance_hold+price);
}
return balance_not_hold;
}
};