Le meilleur moment pour acheter et vendre des actions avec la programmation dynamique LeetCode

L'offre arrive, creusez des amis pour ramasser! Je participe à l'événement de vérification du recrutement du printemps 2022, cliquez pour voir les détails de l'événement .

sujet

Étant donné un tableau d'entiers  prices, où prices[i]représente  le i cours de l'action du jour ; l'entier frais représente les frais de transaction pour l'action.

Vous pouvez effectuer un nombre illimité de transactions, mais vous devrez payer des frais pour chaque transaction. Si vous avez déjà acheté une action, vous ne pouvez pas continuer à l'acheter jusqu'à ce que vous la vendiez.

Renvoie le profit maximum réalisé.

Remarque : une transaction fait ici référence à l'ensemble du processus d'achat, de détention et de vente d'actions, et vous n'avez qu'à payer des frais de traitement pour chaque transaction.

Exemple 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
复制代码

indice:

1 <= prices.length <= 5 * 104
1 <= prices[i] < 5 * 104
0 <= fee < 5 * 104
复制代码

répondre

analyse de résolution de problèmes

Description du sujet : Compte tenu d'un tableau de prix quotidiens des actions, vous pouvez choisir d'acheter ou de vendre chaque jour. Vous ne pouvez pas l'acheter à nouveau lorsque vous le détenez. Il y a des frais de traitement fixes pour chaque transaction. Trouvez le profit maximum qui peut être obtenu .

Idées de résolution de problèmes :

  1. Nous pouvons voir d'après le titre que ce problème est un problème typique de programmation dynamique.
  2. Pour le problème de programmation dynamique, nous pouvons résumer les idées :
    • Définir les équations de transition d'état
    • Étant donné la valeur initiale de l'équation de transition
    • Transférez d'abord l'équation par récursivité du code
  3. En combinant ce sujet, nous définissons d'abord l'équation de transition

Définissez un tableau à deux dimensions dp[n][2] :

  • dp[i][1] représente le profit maximum que l'on peut obtenir en ne détenant pas le i-ème jour ;
  • dp[i][2] représente le profit maximal de la détention le jour i (notez qu'il détient le jour i, et n'achète pas le jour i).

Définissez l'équation de transfert :

  • 不持有: dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prix[i] - frais)

Pour ne pas détenir aujourd'hui, il peut être transféré de deux états, 1. ne pas détenir hier, 2. détenir hier et vendre aujourd'hui. obtenir la valeur maximale

  • 持有: dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prix[i])

Pour l'avoir d'aujourd'hui, il peut être transféré de deux états, 1. Hier est également détenu ; s'il n'est pas détenu hier, achetez aujourd'hui pour obtenir la valeur maximale

  1. initialiser l'équation de transition

Pour le jour 0 : - ne pas conserver : dp[0][0] = 0 ; - conserver (c'est-à-dire acheter avec de l'argent) : dp[0][1] = -prices[0] ;

  1. Le code implémente l'équation de transition
class Solution {
    public int maxProfit(int[] prices, int fee) {
        int n = prices.length;
        int[][] dp = new int[n][2];
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for (int i=0; i< n; i++) {
           dp[i][0] = Math.max(dp[i-1][0], dp[i -1][1] + prices[i] - fee);
           dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
        }
        return dp[n-1][0];
    }
}
复制代码

Comme nous n'avons besoin d'utiliser que les données précédentes, une optimisation de l'espace peut être effectuée. Lors du transfert, dp[i] est transféré de dp[i-1], de sorte que le tableau unidimensionnel peut être supprimé. Le code de la solution finale est affiché.

Analyse de complexité

  • Complexité temporelle : O(N)
  • Complexité spatiale : O(1), nous n'avons pas créé de tableau supplémentaire à stocker.

code de résolution de problèmes

Le code de la solution est le suivant (commentaires détaillés dans le code) :

class Solution {
    public int maxProfit(int[] prices, int fee) {
        int n = prices.length;
        // sell 表示卖出的最大收益
        int sell = 0, buy = -prices[0];
        for (int i = 1; i < n; i++) {
            sell = Math.max(sell, buy + prices[i] - fee);
            buy = Math.max(buy, sell - prices[i]);
        }
        return sell;
    }
}
复制代码

Résultats des commentaires après soumission :

image.png

Informations de référence

Je suppose que tu aimes

Origine juejin.im/post/7080149889576861704
conseillé
Classement