Apprentissage de la version Python-LeetCode: le meilleur moment pour acheter et vendre des actions (121,122,123,188,309,714)

  1. Le meilleur moment pour acheter et vendre des actions, le nombre de transactions K = 1 

Étant donné un tableau, son i-ème élément est le prix d'une action donnée le i-ème jour. Si vous n'êtes autorisé à effectuer qu'une seule transaction au maximum (c'est-à-dire acheter et vendre une action une seule fois), concevez un algorithme pour calculer le profit maximum que vous pouvez réaliser. Remarque: vous ne pouvez pas vendre d'actions avant de les acheter.

Exemple 1: Entrée: [7,1,5,3,6,4] Sortie: 5
Explication: Achetez le 2e jour (cours de l'action = 1) et le 5e jour (cours de l'action = 6) Vendre, le profit maximum = 6-1 = 5.
     Notez que le profit ne peut pas être 7-1 = 6, car le prix de vente doit être supérieur au prix d'achat; en même temps, vous ne pouvez pas vendre l'action avant d'acheter.

Source:
Lien LeetCode : https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock

méthode 1:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        result, buy = 0, float('inf')
        for price in prices:
            if buy > price:
                buy = price
            # 寻找价差最大的那个值
            if result < price - buy:
                result = price - buy

        return result

Méthode 2: utiliser l'idée de programmation dynamique pour considérer

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if prices ==[]: return 0
        n=len(prices)
        
        dp_0,dp_1=0,float('-inf')
        for i in  range(n):
            # 今天我没有持有股票,有两种可能:
            # 要么是我昨天就没有持有,然后今天选择 rest,所以我今天还是没有持有;
            # 要么是我昨天持有股票,但是今天我 sell 了,所以我今天没有持有股票了。
            dp_0=max(dp_0, dp_1+prices[i])
            # 解释:今天我持有着股票,有两种可能:
            # 要么我昨天就持有着股票,然后今天选择 rest,所以我今天还持有着股票;
            # 要么我昨天本没有持有,但今天我选择 buy,所以今天我就持有股票了。
            dp_1=max(dp_1,-prices[i])
            
        return dp_0

 

2. Nombre de transactions K = + infini

Concevez un algorithme pour calculer le profit maximum que vous pouvez obtenir. Vous pouvez effectuer autant de transactions que possible (acheter et vendre une action plusieurs fois).

Remarque: vous ne pouvez pas participer à plusieurs transactions en même temps (vous devez vendre les actions précédentes avant d'acheter à nouveau).

Source:
Lien LeetCode : https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii

méthode 1: 

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        res = 0
        for i in range(1,len(prices)):
            if prices[i]>prices[i-1]:
                res+=prices[i]-prices[i-1]
        return res

Méthode 2:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        dp_0,dp_1=0,float('-inf')
        for price in prices:
            # 
            tmp=dp_0
            # 
            dp_0=max(dp_0,dp_1+price)
            dp_1=max(dp_1,tmp-price)
        return dp_0

 

309. Le meilleur moment pour acheter et vendre des actions comprend une période de gel

Étant donné un tableau d'entiers, le i-ème élément représente le cours de l'action le i-ème jour. Concevez un algorithme pour calculer le profit maximum. Sous les contraintes suivantes, vous pouvez effectuer autant de transactions que possible (acheter et vendre une action plusieurs fois): Vous ne pouvez pas participer à plusieurs transactions en même temps (vous devez vendre l'action précédente avant d'acheter à nouveau).
Après avoir vendu le stock, vous ne pouvez pas acheter le stock le jour suivant (c'est-à-dire que la période de gel est de 1 jour).

Exemple: Entrée: [1,2,3,0,2] Sortie: 3 Explication: Le statut de la transaction correspondante est: [Achat, Vente, Gel de la période, Achat, Vente]

Source:
Lien LeetCode : https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown

méthode 1:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices:
            return 0
        n = len(prices)
        # f[i][0]: 手上持有股票的最大收益
        # f[i][1]: 手上不持有股票,并且处于冷冻期中的累计最大收益
        # f[i][2]: 手上不持有股票,并且不在冷冻期中的累计最大收益
        f = [[-prices[0], 0, 0]] + [[0] * 3 for _ in range(n - 1)]
        for i in range(1, n):
            f[i][0] = max(f[i - 1][0], f[i - 1][2] - prices[i])
            f[i][1] = f[i - 1][0] + prices[i]
            f[i][2] = max(f[i - 1][1], f[i - 1][2])
        
        return max(f[n - 1][1], f[n - 1][2])

Méthode 2:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        dp_0,dp_1=0,float('-inf')
        # 没有持有的前一天的卖出状态
        dp_pre_0=0

        for p in prices:
            tmp=dp_0   # 卖出值

            dp_0=max(dp_0,dp_1+p)   # 卖出阶段
            # 比较继续持有,前一天卖出值减去p的总值
            dp_1=max(dp_1,dp_pre_0-p)   # 持有阶段
            # 获取卖出值,作为前一天卖出操作值
            dp_pre_0=tmp

        return dp_0

 

714. 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: LeetCode
Lien: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee
Méthode 1:

class Solution:
    def maxProfit(self, prices: List[int], fee: int) -> int:

        dp_0,dp_1=0,float('-inf')

        for p in prices:
            tmp=dp_0  # 昨天卖出后获得的利润
            dp_0=max(dp_0,dp_1+p-fee)  # 今天卖出状态下的利润
            dp_1=max(dp_1,dp_0-p)      # 今天持有状态下的利润;
            # dp_0-p,是前天卖出后,今天买入下的利润状态

        return dp_0

Méthode 2:

class Solution:
    def maxProfit(self, prices: list, fee: int) -> int:
        if len(prices) < 2:
            return 0
        profit = 0
        buy = sold = prices[0]
        for price in prices[1:]:
            if price > sold:
                sold = price
            else:
                gain = sold - buy - fee
                if gain >0 and gain > price-buy:
                    profit += gain
                    buy = sold = price
                elif price < buy:
                    buy = sold = price
        if sold - buy > fee:
            profit += sold - buy - fee
        return profit

 

 123. Le meilleur moment pour acheter et vendre des actions III   , le nombre de transactions K = 2

Étant donné un tableau, son i-ème élément est le prix d'une action donnée le i-ème jour. Concevez un algorithme pour calculer le profit maximum que vous pouvez obtenir. Vous pouvez effectuer jusqu'à deux transactions. Remarque: vous ne pouvez pas participer à plusieurs transactions en même temps (vous devez vendre les actions précédentes avant d'acheter à nouveau).

Exemple 1: Entrée: [3,3,5,0,0,3,1,4]
Sortie: 6
Explication: Achetez le 4e jour (cours de l'action = 0) et le 6e jour (cours de l'action = 3) Lorsque vous vendez, l'échange peut faire un profit = 3-0 = 3.
     Ensuite, achetez le 7ème jour (cours de l'action = 1) et vendez le 8e jour (cours de l'action = 4). L'échange peut faire un profit = 4-1 = 3.

Source: LeetCode Lien: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii
Méthode 1:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # 一次交易,初始化
        dp_i10,dp_i11=0,float('-inf')
        # 第二次交易初始化
        dp_i20,dp_i21=0,float('-inf')

        for p in prices:
            # 第二次卖出,第二次卖出的时候就是最后的总利润值,
            # 最后的利润等于,这次买入后的利润(dp_i20)加上目前的价格
            dp_i20=max(dp_i20,dp_i21+p)
            # 第二次买入,第一次卖出获得的利润减去当前价格,与上次的计算第二次买入利润相比较
            dp_i21=max(dp_i21,dp_i10-p)
            # 第一次卖出,第一次买入的利润加p,与上次的第一次买入进行利润比较
            dp_i10=max(dp_i10,dp_i11+p)
            # 第一次买入,第一次的买入与-价格p比较
            dp_i11=max(dp_i11,-p)
        return dp_i20

Méthode 2:

 n = len(prices)
        if n < 2:
            return 0
        
        # 维护两个数组,从左到右,从右到左 找出最大利润的两笔交易
        left = [0] * n
        min_p = prices[0]
        max_p = 0
        # 第i天的最大利润 = max(第i-1天的利润,第i天的价格 - 第i-1天内最小价格)
        for i in range(1, n):
            max_p = max(max_p, prices[i] - min_p)
            min_p = min(min_p, prices[i])
            left[i] = max_p
        # print(left)

        # 第i天的最大利润 = max()
        right = [0] * n
        min_p = prices[-1]
        max_p = 0
        # 注意这里要从倒数第二天开始遍历 n-2天 n = 8 
        for i in range(n-2, -1, -1):
            # 倒序第6天的最大收益 = max(第7天的最大收益, 前7天的最大价格 - 第6天的价格)
            max_p = max(max_p, min_p - prices[i])
            min_p = max(min_p, prices[i])
            right[i] = max_p + left[i]
        
        return max(right)

 

188. Le meilleur moment pour acheter et vendre des actions IV   , le nombre de transactions K = tout entier 

Étant donné un tableau, son i-ème élément est le prix d'une action donnée le i-ème jour. Concevez un algorithme pour calculer le profit maximum que vous pouvez obtenir. Vous pouvez effectuer jusqu'à k transactions. Remarque: vous ne pouvez pas participer à plusieurs transactions en même temps (vous devez vendre les actions précédentes avant d'acheter à nouveau).

Exemple 1: Entrée: [2,4,1], k = 2 Sortie: 2
Explication: Achetez le premier jour (cours de l'action = 2) et vendez le deuxième jour (cours de l'action = 4) , Cet échange peut faire un profit = 4-2 = 2.

Source:
Lien LeetCode : https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv

méthode 1:

class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        n=len(prices)
        if k > n/2:
            dp_0,dp_1=0,float('-inf')
            for p in prices:
                tmp=dp_0
                dp_0=max(dp_0,dp_1+p)
                dp_1=max(dp_1,tmp-p)
            return dp_0
        else:
            dp=[[[0,0] for i in range(k+1)] for i in range(len(prices))]

            for i,p in enumerate(prices):

                for k in range(1,k+1):
                    if i==0:
                        dp[i][k][0]=0
                        dp[i][k][1]=-p
                        continue
                    # 第i天的第k次操作的卖出状态,
                    dp[i][k][0]=max(dp[i-1][k][0],dp[i-1][k][1]+p)
                    dp[i][k][1]=max(dp[i-1][k][1],dp[i-1][k-1][0]-p)
            # print(dp)
            return dp[n-1][k][0]

 

Je suppose que tu aimes

Origine blog.csdn.net/guyu1003/article/details/107447017
conseillé
Classement