Python version-LeetCode learning: the best time to buy and sell stocks (121,122,123,188,309,714)

  1. The best time to buy and sell stocks, the number of transactions K=1 

Given an array, its i-th element is the price of a given stock on the i-th day. If you are only allowed to complete one transaction at most (that is, buy and sell a stock once), design an algorithm to calculate the maximum profit you can make. Note: You cannot sell stocks before buying them.

Example 1: Input: [7,1,5,3,6,4] Output: 5
Explanation: Buy on the 2nd day (stock price = 1), and on the 5th day (stock price = 6) Sell, the maximum profit = 6-1 = 5.
     Note that the profit cannot be 7-1 = 6, because the selling price needs to be greater than the buying price; at the same time, you cannot sell the stock before buying.

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

method 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

Method 2: Use the idea of ​​dynamic programming to consider

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. Number of transactions K=+infinity

Design an algorithm to calculate the maximum profit you can get. You can complete as many transactions as possible (buying and selling a stock multiple times).

Note: You cannot participate in multiple transactions at the same time (you must sell the previous stocks before buying again).

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

method 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

Method 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. The best time to buy and sell stocks includes a freezing period

Given an integer array, the i-th element represents the stock price on the i-th day. ​Design an algorithm to calculate the maximum profit. Under the following constraints, you can complete as many transactions as possible (buying and selling a stock multiple times): You cannot participate in multiple transactions at the same time (you must sell the previous stock before buying again).
After selling the stock, you cannot buy the stock the next day (ie, the freezing period is 1 day).

Example: Input: [1,2,3,0,2] Output: 3 Explanation: The corresponding transaction status is: [Buy, Sell, Freeze Period, Buy, Sell]

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

method 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])

Method 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. The best time to buy and sell stocks includes handling fees

Given an integer array prices, the i-th element represents the stock price on the i-th day; the non-negative integer fee represents the transaction cost of stocks.

You can complete transactions unlimited times, but you will need to pay a handling fee for each transaction. If you have already bought a stock, you can no longer buy stocks before you sell it. Returns the maximum profit obtained.

Note: A transaction here refers to the entire process of buying, holding and selling stocks. You only need to pay a handling fee for each transaction.

Source: LeetCode
Link: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee
Method 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

Method 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. The best time to buy and sell stock III   , the number of transactions K=2

Given an array, its i-th element is the price of a given stock on the i-th day. Design an algorithm to calculate the maximum profit you can get. You can complete up to two transactions. Note: You cannot participate in multiple transactions at the same time (you must sell the previous stocks before buying again).

Example 1: Input: [3,3,5,0,0,3,1,4]
Output: 6
Explanation: Buy on the 4th day (stock price = 0), and on the 6th day (stock price = 3) When you sell, the exchange can make a profit = 3-0 = 3.
     Then, buy on the 7th day (stock price = 1), and sell on the 8th day (stock price = 4). The exchange can make a profit = 4-1 = 3.

Source: LeetCode Link: https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii
Method 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

Method 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. The best time to buy and sell stock IV   , the number of transactions K= any int 

Given an array, its i-th element is the price of a given stock on the i-th day. Design an algorithm to calculate the maximum profit you can get. You can complete up to k transactions. Note: You cannot participate in multiple transactions at the same time (you must sell the previous stocks before buying again).

Example 1: Input: [2,4,1], k = 2 Output: 2
Explanation: Buy on the 1st day (stock price = 2), and sell on the 2nd day (stock price = 4) , This exchange can make a profit = 4-2 = 2.

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

method 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]

 

Guess you like

Origin blog.csdn.net/guyu1003/article/details/107447017