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.贪心算法

买入点:遇见低点就买入
卖出点:今天价格-买入价格-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;
}
}
浙公网安备 33010602011771号