【LeetCode】解题714:Best Time to Buy and Sell Stock with Transaction Fee(动态规划)

LeetCode解题 714:Best Time to Buy and Sell Stock with Transaction Fee (动态规划)

Problem 714: Best Time to Buy and Sell Stock with Transaction Fee [Medium]

Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; and a non-negative integer fee representing a transaction fee.

You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.)

Return the maximum profit you can make.

Example:

Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
Output: 8
Explanation: The maximum profit can be achieved by:

  • Buying at prices[0] = 1
  • Selling at prices[3] = 8
  • Buying at prices[4] = 4
  • Selling at prices[5] = 9

The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.

来源:LeetCode

解题思路

本题仍然需要使用动态规划思想。与题解309:Best Time to Buy and Sell Stock with Cooldown同属于最佳时机买卖股票问题。

解题思路与309题基本类似,只需要增加一项手续费,并且去掉冷却期。依旧使用maxP的状态转移方程,每天的maxP分为两种:maxP0和maxP1,分别代表当天不持有股票和当天持有股票的最大利润。第i天的maxP0可以由第i-1天的maxP0和maxP1转移,第i天的maxP1也是由第i-1天的maxP1和maxP0转移,但是由maxP0转移时,需要增加手续费。

状态转移方程为:
m a x P 0 [ i ] = max ⁡ { m a x P 0 [ i − 1 ] , m a x P 1 [ i − 1 ] + p r i c e s [ i ] } m a x P 1 [ i ] = max ⁡ { m a x P 1 [ i − 1 ] , m a x P 0 [ i − 1 ] − p r i c e s [ i ] − f e e } maxP_0[i] = \max\{maxP_0[i-1], maxP_1[i-1] + prices[i]\} \\ maxP_1[i] = \max\{maxP_1[i-1], maxP_0[i-1] - prices[i] - fee\} maxP0[i]=max{maxP0[i1],maxP1[i1]+prices[i]}maxP1[i]=max{maxP1[i1],maxP0[i1]prices[i]fee}
其中, m a x P 1 [ i − 1 ] + p r i c e s [ i ] maxP_1[i-1] + prices[i] maxP1[i1]+prices[i]的意思是第i-1天持有的股票在当前天卖出; m a x P 0 [ i − 1 ] − p r i c e s [ i ] − f e e maxP_0[i-1] - prices[i] - fee maxP0[i1]prices[i]fee的意思是第i-1天之前卖出的股票在当前天买入,并且支付手续费。

由于maxP0更新只使用到前一天的maxP0和maxP1,maxP1更新也只使用到前一天的maxP1和maxP0,因此可以不使用maxP0[N]和maxP1[N]来存储,只需使用常数空间。
状态转移更新为:
m a x P 0 = max ⁡ { m a x P 0 , m a x P 1 + p r i c e s [ i ] } m a x P 1 = max ⁡ { m a x P 1 , p r e m a x P 0 − p r i c e s [ i ] − f e e } maxP_0 = \max\{maxP_0, maxP_1 + prices[i]\} \\ maxP_1 = \max\{maxP_1, premaxP_0 - prices[i] - fee\} maxP0=max{maxP0,maxP1+prices[i]}maxP1=max{maxP1,premaxP0prices[i]fee}
其中, m a x P 0 maxP_0 maxP0初始化为0, m a x P 1 maxP_1 maxP1初始化为-prices[0]-fee, p r e m a x P 0 premaxP_0 premaxP0指i-1天的 m a x P 0 maxP_0 maxP0

该方法时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)

运行结果:
在这里插入图片描述
要点:动态规划

Solution (Java)

class Solution {
    public int maxProfit(int[] prices, int fee) {
        int N = prices.length;
        if(N < 2) return 0;
        int maxP0 = 0;
        int maxP1 = -prices[0] - fee;
        int pre_maxP0;
        for(int i = 1; i < N; i++){
            pre_maxP0 = maxP0;
            maxP0 = Math.max(maxP0, maxP1 + prices[i]);
            maxP1 = Math.max(maxP1, pre_maxP0 - prices[i] - fee);
        }
        return maxP0;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值