714.买卖股票的最佳时机含手续费

  • 714.买卖股票的最佳时机含手续费

  • 题目:
    数组prices的每个元素prices [ i ]代表每天的价格,选择买入卖出时机,返回最多赚的钱;

  • 思路:
    1.贪心:O(n),O(1)
    本题用贪心解决的话,关注点并不在具体的买入和卖出日期上,而是将利润分解开计算的,但分解开的这些操作与实际操作其实也是有一定对应关系的;
    minPrice并不一定是真正实际操作时的买入价格:实际一笔交易的利润,在计算时可能会被分解开,minPrice充当每一次计算利润时的买入价格;
    每次计算利润时,都会扣手续费。若一笔实际交易只对应一次利润计算,这样刚好; 但若一笔实际交易对应多次利润计算,则需要提前弥补minPrice,防止后面几次多次扣手续费。
    在每次计算利润后,minPrice = prices[i] - fee,这句很重要。后面可能还是同一笔交易的利润计算,也有可能遇到更低的prices[ ] 值,说明前面这笔交易确实结束了,又将进行一笔新交易;

class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
        int res = 0;
        int minPrice = prices[0]; //记录最低价格
        for (int i = 1; i < prices.size(); ++i) {
            //说明价格很低就买入
            minPrice = prices[i] < minPrice ? prices[i] : minPrice;

            //说明价格比minPrice高,但高的不多,此时卖则亏本,买也不便宜
            if (prices[i] >= minPrice && prices[i] <= minPrice + fee) continue;

            //说明价格比minPrice高很多,就计算一次利润(扣手续费),但这不代表真正卖出操作; 
            //若对应到实际操作相当于一笔实际交易分为几次利润计算,手续费在第一次计算时就扣了,后面计算利润时相当于降低了买入价格
            if (prices[i] > minPrice + fee) {
                res += prices[i] - (minPrice + fee);//一笔交易只扣一次手续费
                minPrice = prices[i] - fee; //对于连续利润,在第一天计算利润时已经扣了一次手续费,因此后续几天不能再扣了
            }
        }
        return res;
    }
};

2.DP:O(n),O(1)
滚动记录前一天的两个值,用于更新今天的两个值;

class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
        int holdStack_Max = (-1) * prices[0]; //持有股票时的最多现金
        int noStack_Max = 0; //不持有股票时的最多现金
        for (int i = 1; i < prices.size(); ++i) {
            int pre_holdStack_Max = holdStack_Max; //备份一下,因为下面改了holdStack_Max后,noStack_Max还要用
            holdStack_Max = max(holdStack_Max, noStack_Max - prices[i]);
            noStack_Max = max(noStack_Max, holdStack_Max + prices[i] - fee); //在卖出时扣手续费
        }
        return noStack_Max;
    }
};
  • 总结:
    本题贪心需要考虑清楚细节,但DP有点黑盒子的感觉
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值