leetcode 714. Best Time to Buy and Sell Stock with Transaction Fee 遍历、递推、状态转移

本文探讨了在考虑交易费用的情况下,寻找最佳股票买卖时机的问题。通过两种算法对比,一种是遍历法,另一种是动态规划法。遍历法考虑低买高卖策略并计算可能利润,而动态规划法则关注于持有和不持有股票状态的最大收益,最终目标是找到最大账户余额。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值