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

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

题目

给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。

示例 1:

输入:prices = [1, 3, 2, 8, 4, 9], fee = 2
输出:8
解释:能够达到的最大利润:  
在此处买入 prices[0] = 1
在此处卖出 prices[3] = 8
在此处买入 prices[4] = 4
在此处卖出 prices[5] = 9
总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8

示例 2:

输入:prices = [1,3,7,5,10,3], fee = 3
输出:6

提示:

1 <= prices.length <= 5 * 104
1 <= prices[i] < 5 * 104
0 <= fee < 5 * 104

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解1.贪心算法

image

买入点:遇见低点就买入
卖出点:今天价格-买入价格-fee>0,有利润就卖出。有手续费,要把峰-fee降低,降低后才能看出是不是真的峰。

所以我们在做收获利润操作的时候其实有三种情况:

情况一:有利润有可能不是真正的卖出点,比如递增,今天有利润,明天也有利润,那么真实的卖出点是明天。
情况二:真正的卖出点,那么就需要重新记录买入值。
情况三:继续持有

class Solution {
    public int maxProfit(int[] prices, int fee) {
        int len = prices.length;
        if(len==1) return 0;	
        int profit = 0 ;
        int buyprice = prices[0];
        for(int i=1;i<len;i++){
            if(prices[i]<buyprice)buyprice = prices[i];//比当前值低就买入
	    //有利润就卖出
            if(prices[i]-buyprice-fee>0){//今天获取的利润,假设卖出了,有可能不是真正的卖出点,但是已经减了交易费用
                profit+=prices[i]-buyprice-fee;
                buyprice = prices[i] - fee; //情况1,这样在明天收获利润的时候,才不会多减一次手续费!
            }
        }
        return profit;
    }
}

题解2.动态规划

这道题和122有类似之处,只不过多了一个手续费。我们假设一笔收益在买入的时候扣除手续费。

dp数组定义与初始化
每一天还是只有两种状态:持有与不持有。

  • dp[i][0]:表示第i天不持有状态下的最大利润
  • dp[i][1]:表示第i天持有状态下的最大利润

假设第i天是不持有状态

  • 如果第i天没有执行操作,dp[i][0] = dp[i-1][0]
  • 如果第i天执行了卖出操作,dp[i][0] = dp[i-1][1] + prices[i]
    dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1] + prices[i])

如果第i天是持有状态

  • 如果第i天没有执行操作,dp[i][1] = dp[i-1][1]
  • 如果第i天执行了买入操作,dp[i][1] = dp[i-1][0] - prices[i] - fee
    dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0] - prices[i] - fee)

数组初始化
dp[0][0] = 0
dp[0][1] = - prices[0] - fee

空间优化
第i天的情况只与第i-1天的有关,那么使用两个变量代替。

int off = 0;
int on = - prices[0] - fee;
int temp = 0;
for(int i=1;i<prices.length;i++){
  temp = off;
  off  = Math.max(off,on  + prices[i]);
  on = Math.max(on  ,temp  - prices[i] - fee);
}

代码

class Solution {
    public int maxProfit(int[] prices, int fee) {
    int len = prices.length;
    if(len==1) return 0;
    int off = 0;
    int on = - prices[0] - fee;
    int temp = 0;
    for(int i=1;i<len;i++){
        temp = off;
        off  = Math.max(off,on  + prices[i]);
        on = Math.max(on  ,temp  - prices[i] - fee);
    }
    return off;
    }
}
posted @ 2021-08-10 16:34  rananie  阅读(46)  评论(0)    收藏  举报