Le meilleur moment pour acheter et vendre des actions comprend les frais de traitement
Étant donné les prix d'un tableau d'entiers, le i-ème élément représente le cours de l'action le i-ème jour; les frais entiers non négatifs représentent les frais de transaction pour les actions.
Vous pouvez effectuer des transactions indéfiniment, mais vous devez payer des frais de traitement pour chaque transaction. Si vous avez déjà acheté une action, vous ne pouvez plus acheter d'actions avant de la vendre.
Renvoie le profit maximum obtenu.
Remarque: Ici, une transaction fait référence à l'ensemble du processus d'achat, de détention et de vente d'actions. Vous ne devez payer que des frais de traitement pour chaque transaction.
(Source sujet: LeetCode )
示例 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.
注意:
0 < prices.length <= 50000.
0 < prices[i] < 50000.
0 <= fee < 50000.
Deux, la solution
- Programmation dynamique
public static int maxProfit(int[] prices, int fee) {
//状态数组
int[][] dp=new int[prices.length][2];
//第一天手中没有股票的最大收益
dp[0][0]=0;
//第一天手中有股票的最大收益
dp[0][1]=-prices[0];
for (int i = 1; i < dp.length; i++) {
//第i天无股票的最大收益是在前一天最大收益和今天卖出股票的最大收益中的最大的那个金额
dp[i][0]=Math.max(dp[i-1][0], dp[i-1][1]+prices[i]-fee);
//第i天有股票的最大收益就等于i-1天买进今天股票后的金额
dp[i][1]=Math.max(dp[i-1][1], dp[i-1][0]-prices[i]);
}
//第prices.length-1天手中无股票的最大收益总是大于手中有股票的最大收益
return dp[prices.length-1][0];
}
- Optimisation de la programmation dynamique
public static int maxProfit(int[] prices, int fee) {
//第一天手中没有股票的最大收益
int nP=0;
//第一天手中有股票的最大收益
int yP=-prices[0];
for (int i = 1; i < prices.length; i++) {
//第i天无股票的最大收益是在前一天最大收益和今天卖出股票的最大收益中的最大的那个金额
nP=Math.max(nP, yP+prices[i]-fee);
//第i天有股票的最大收益就等于i-1天买进今天股票后的金额
yP=Math.max(yP, nP-prices[i]);
}
//第prices.length-1天手中无股票的最大收益总是大于手中有股票的最大收益
return nP;
}
- Comment vas-tu
public int maxProfit(int[] prices, int fee) {
int length=prices.length;
//这次买股票并支付之后卖出时所需要用得手续费
int buy=prices[0]+fee;
//总收益
int profit=0;
for (int i = 1; i < length; i++) {
if(buy>prices[i]+fee){
//如果这一次购买股票加手续费比上一次还少,直接买这股
buy=prices[i]+fee;
}else if(buy<prices[i]){
//如果这次得股价比现在股价加手续费还高,直接卖出
profit+=prices[i]-buy;
//注意这次没有加上手续费,如果下次进入第一个if,这个也就舍弃了没事
//再次进入第二个if时说明卖早了,此时再卖出(中间直接省略了费用计算)就相当于一次贪心
buy=prices[i];
}
}
return profit;
}