[LeetCode] 714. Best Time to Buy and Sell Stock with Transaction Fee

本文探讨了在考虑交易费用的情况下,如何通过动态规划法确定最佳的股票买卖时机以实现最大利润。通过分析两种状态(未持有股票和持有股票)的状态转移方程,提供了两种实现代码,一种使用数组,另一种则优化为仅使用变量。

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

原题链接:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/

Buy and Sell Stock专题相关题目

121. Best Time to Buy and Sell Stock
122. Best Time to Buy and Sell Stock II
123. Best Time to Buy and Sell Stock III
188. Best Time to Buy and Sell Stock IV
309. Best Time to Buy and Sell Stock with Cooldown
714. Best Time to Buy and Sell Stock with Transaction Fee

1. 题目介绍

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.

给出一个数组,第 i 个数代表着某支股票在第 i 天的价格,并且还给出一个非负数,是每一次交易的费用。可以无限次交易股票,但是必须先买后卖,不能同时买卖。最终求最大获利。

Example 1:
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.

Note:
0 < prices.length <= 50000.
0 < prices[i] < 50000.
0 <= fee < 50000.

2. 解题思路

动态规划法

这道题的解法和 309. Best Time to Buy and Sell Stock with Cooldown 非常相像,都是借助有限状态机的动态规划法。

根据题意,有两种状态:
s0:没有买股票,也没有卖。
s1:已经买了股票,但是尚未卖出

状态转换图如下所示,共有2个状态,4条边,每天都必须走一条边。
在这里插入图片描述
依照状态转移图,找到了状态转移方程:

s0[i] = max(s0[i-1], s1[i-1]-fee+prices[i] )
s1[i] = max(s1[i-1], s0[i-1]-prices[i] )

找到状态转移方程后,就可以写出实现代码了。
实现代码1

class Solution {
    public int maxProfit(int[] prices, int fee) {
        int length = prices.length;
        if(length ==0 || prices == null) {
        	return 0;
        }
        
        int[] s0 = new int[length];
        int[] s1 = new int[length];
        
        s0[0] = 0;
        s1[0] = 0- prices[0];
        
        for(int i =1 ; i<length ; i++) {
        	s0[i] = Math.max(s0[i-1], s1[i-1]-fee+prices[i]);
        	s1[i] = Math.max(s1[i-1], s0[i-1]-prices[i]);
        }

        return Math.max(s0[length-1], s1[length-1]);
    }
}

进一步优化

由于每一次更新 s0[ i ] 或者 s1[ i ],用到的都是 s0[ i-1 ] 或者 s1[ i-1 ]的值,不会用到数组的其他部分。我们也可以不使用数组,直接用变量来替代数组。

实现代码2

class Solution {
    public int maxProfit(int[] prices, int fee) {
        int length = prices.length;
        if(length ==0 || prices == null) {
        	return 0;
        }
        
        int s0 = 0;
        int s1 = 0- prices[0];
        int temp0,temp1;
        
        for(int i =1 ; i<length ; i++) {
        	temp0 = s0;
        	temp1 = s1;
        	
        	s0 = Math.max(s0, s1-fee+prices[i]);
        	s1 = Math.max(temp1, temp0-prices[i]);
        }
        
        
        return Math.max(s0, s1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值