“Leetcode” the best time to buy and sell stocks I, II, III, IV, including handling charges, including freezing period

Time:2020-6-19

preface

A series of interview questions with high attendance rate. In half a year, there are 18 headlines, 4 Ali and 3 Xiaomi (I bought members so I can see the attendance rate). It’s a must to see interview recently.

121. The best time to buy and sell stocks (simple)

Original question

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

Example 1:

Input: [7,1,5,3,6,4]
Output: 5
Explanation: buy on day 2 (stock price = 1) and sell on day 5 (stock price = 6). 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.

Example 2:

Input: [7,6,4,3,1]
Output: 0
Explanation: in this case, there is no transaction completed, so the maximum profit is 0.

thinking

Note: the number of transactions is limited to1Times.

  • The firstiday

    • If theiDays holding shares. There are two possibilitiesiDays holding shares.

      1. Buy shares today
      2. I bought stocks before today
    • If theiDay does not hold shares. There are two possibilitiesiDay does not hold shares.

      1. I don’t own stocks today
      2. Sell your own shares today
  • On the first day, the share price was7

    • The purchase of shares is an expense, so if you purchase shares on the first day, the maximum profit is0 - 7 = -7
    • No shares on the first day, profit is0
  • The next day, the share price was1

    • We need to maximize profits, so the lower the stock price, the better. The next day’s share price is1Better than the first day7So we should choose to buy stocks the next day, and the maximum profit is0 - 1 = -1。 (because the problem itself limits the number of transactions, there is no dividendNot equal to0Situation)
    • There are two possibilities of not holding shares the next day (the next day itself does not hold shares, and the status follows the previous day’s status). Or, sell your shares at today’s share price. The first possibility, the maximum benefit is0, the second possibility, the maximum benefit is1 - 7 = -6, less than0。 So our biggest payoff the next day should be0
  • On the third day, the share price is5

    • On the third day, the share price is5It’s higher than the day before, so we still choose to buy stocks the day before, and the biggest profit of the third day when we hold stocks is still-1
    • There are two possibilities for not holding shares on the third day. The first possibility is to follow the previous day’s status, and the income is still0。 The second possibility is to sell the currently held shares at today’s share price, and the profit is5 - 1 = 4(current share price – the best value or the lowest cost value when holding shares on the previous day), the result is4, better than the first possibility. So the maximum return on the third day is4

And so on. Find out the maximum value in the optimal result array without holding stocks. (Because when you don’t hold shares, you have no burden)。

code

var maxProfit = function(prices) {
    if (prices.length === 0 || prices.length === 1) {
        return 0
    }
    //DP1 array stores the 'I' day, the maximum profit of the stock
    const dp1 = []
    dp1[0] = -prices[0]
    //DP2 array stores the 'I' day, the maximum profit of not holding shares
    const dp2 = []
    dp2[0] = 0
    
    for (let i = 1; i < prices.length; i++) {
        dp1[i] = Math.max(dp1[i - 1], -prices[i])
        dp2[i] = Math.max(dp2[i - 1], prices[i] + dp1[i - 1])
    }
    
    return dp2[dp2.length - 1]
};

122. The best time to buy and sell stocks II (simple)

Original question

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 do as many trades as you can (buy and sell a stock multiple times).

Note: you cannot participate in more than one transaction at a time (you must sell the previous shares before you buy again).

Example 1:

Input: [7,1,5,3,6,4]
Output: 7
Explanation: buy on the second day (stock price = 1) and sell on the third day (stock price = 5). The exchange will get profit = 5-1 = 4.
     Then, buy on day 4 (stock price = 3) and sell on day 5 (stock price = 6), and the exchange will get profit = 6-3 = 3.

Example 2:

Input: [1,2,3,4,5]
Output: 4
Explanation: buy on the first day (stock price = 1) and sell on the fifth day (stock price = 5). The exchange will get profit = 5-1 = 4.
     Note that you cannot buy shares on day 1 and day 2 in succession and then sell them.
     Because it's involved in multiple transactions at the same time, you have to sell the shares before you buy them again.

thinking

Note: this question does not limit the number of transactions (309, 714 can be regarded as the extension of this question)

Different from the first question, this topic is that you can make unlimited transactions. So our revenue can beaccumulationOf. The most direct embodiment of the influence on the state transfer equation is thatThe firstiThe optimal solution of day holding stockWe need to think about the day before, not from0Start. Therefore, the equation of state transfer of holding stock is derived from,Max (previous day's status, 0 - today's share price)Change toMax (previous day's status, previous day's optimal return - today's share price)

We can deduce the logic according to the above question and so on. Finally, back to the last dayNo shares heldWhen the best income.

code


/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(prices) {
    if (prices.length === 0 || prices.length === 1) {
        return 0
    }
    
    const dp1 = []
    dp1[0] = -prices[0]
    
    const dp2 = []
    dp2[0] = 0
    
    for (let i = 1; i < prices.length; i++) {
        dp1[i] = Math.max(dp1[i - 1], dp2[i - 1] - prices[i])
        dp2[i] = Math.max(dp2[i - 1], prices[i] + dp1[i - 1])
    }
    
    return dp2[prices.length - 1]
};

714. The best time to buy or sell shares includes handling fee (medium)

Original question

Given an integer array of prices, where the i-th element represents the stock price on the i-th day; the non negative integer fee represents the handling charge for trading stocks. You can complete the transaction indefinitely, but you need to pay a commission for each transaction. If you’ve already bought a stock, you can’t keep buying until you sell it. Returns the maximum profit earned.

Example 1:

Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
Output: 8
Explanation: the maximum profit that can be achieved:  
Buy prices here [0] = 1
Sell prices here [3] = 8
Buy prices here [4] = 4
Sell prices here [5] = 9
Total profit: ((8 - 1) - 2) + ((9 - 4) - 2) = 8

thinking

The question is122We only need to consider the handling fee when selling the stockfeeJust.

code


/**
 * @param {number[]} prices
 * @param {number} fee
 * @return {number}
 */
var maxProfit = function(prices, fee) {
    if (prices.length === 0 || prices.length === 1) {
        return 0
    }
    
    const dp1 = []
    dp1[0] = -prices[0]

    const dp2 = []
    dp2[0] = 0
    
    for (let i = 1; i < prices.length; i++) {
        dp1[i] = Math.max(dp1[i - 1], dp2[i - 1] - prices[i])
        dp2[i] = Math.max(dp2[i - 1], prices[i] + dp1[i - 1] - fee)
    }
    
    return dp2[dp2.length - 1]
};

309. The best time to buy and sell stocks includes freezing period (medium)

Original question

Given an array of integers where the i-th element represents the i-th day’s stock price. Design an algorithm to calculate the maximum profit. You can complete as many transactions as you can (buy and sell one stock multiple times) with the following constraints:

  • You can’t participate in multiple transactions at the same time (you have to sell the shares before you buy again).
  • After you sell your shares, you can’t buy them the next day (i.e. the freezing period is one day).

Example:

Input: [1,2,3,0,2]
Output: 3 
Explanation: the corresponding transaction status is: [buy, sell, frozen period, buy, sell]

thinking

This question is still122But there are some differences.

Trading shares are divided intopurchasesell outTwo steps.purchaseThe operation is limited by the freezing period, butsell outIt is not limited by the freezing period. According to the rules of freezing period, we need toThe state transfer equation of holding stockAdjust to the figure above. But many people see the above formula, and will ask the following question.

Q: NoiWhy does the optimal state of day’s holding stock come from thei - 2Days do not hold the state obtained, Noi-1Does it have to be frozen?

A: SectioniThere are two possible ways to hold shares. The first possibility,Own stock, continuei-1Day status。 The second possibility,In order toiTian’s share price, then we need to consider, Noi-1Days do not hold stock status.

If thei-1Day is the freezing period. So, Noi-1The state of heaven is bound toi-2The days are equal.

If thei-1Day is not the freezing period. There are two possibilities. The first possibility,The firsti-1Day itself does not hold shares, so we need to get thei-2Day status。 The second possibility, the secondi-1Days to sell shares, due to the limitation of freezing period, NoiWe can’t buy stocks in days, so this may not work (whether it’s freezing or not, we can’ti-1Days to sell shares).

According to the above analysis. Regardless of thei-1Is it freezing? We all need toi-2Day does not hold the stock the optimal solution carries on the computation.

code


/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(prices) {
    if (prices.length === 0 || prices.length === 1) {
        return 0
    }
    
    const dp1 = []
    dp1[0] = -prices[0]

    const dp2 = []
    dp2[0] = 0
    
    for (let i = 1; i < prices.length; i++) {
        let temp = dp2[i - 2] === undefined ? 0 : dp2[i - 2]
        dp1[i] = Math.max(dp1[i - 1], temp - prices[i])
        dp2[i] = Math.max(dp2[i - 1], prices[i] + dp1[i - 1])
    }
    
    return dp2[dp2.length - 1]
};

123. The best time to buy and sell shares III (difficult)

Original question

Given an array, its i-th element is the price of a given stock on day I.

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 shares before you buy again).

Example 1:

Input: [3,3,5,0,0,3,1,4]
Output: 6
Explanation: buy on the 4th day (stock price = 0) and sell on the 6th day (stock price = 3). The exchange will get profit = 3-0 = 3.
     Then, buy on day 7 (stock price = 1) and sell on day 8 (stock price = 4), and the exchange will get profit = 4-1 = 3.

Example 2:

Input: [1,2,3,4,5]
Output: 4
Explanation: buy on the first day (stock price = 1) and sell on the fifth day (stock price = 5). The exchange will get profit = 5-1 = 4.   
     Note that you cannot buy shares on day 1 and day 2 in succession and then sell them.   
     Because it's involved in multiple transactions at the same time, you have to sell the shares before you buy them again.

thinking

The thinking of this question needs to add a latitude, before we only need to considerholdAndNot heldIn two cases, we have increased it to four.Holding shares, two more trading opportunitiesHolding shares, another trading opportunityNo shares, two more trading opportunitiesNo shares, another trading opportunity

code

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(prices) {
    if (prices.length === 0 || prices.length === 1) {
        return 0
    }
    
    //Shares held
    const dp1 = [
        [- prices [0]], // there are still two trading opportunities left
        [- prices [0]] // one more trading opportunity left
    ]
    //No shares held
    const dp2 = [
        [0], // two trading opportunities remaining
        [0] // one trading opportunity left
    ]
    
    for (let i = 1; i < prices.length; i++) {
        //Shares held,还有两次交易机会
        dp1[0][i] = Math.max(dp1[0][i - 1], -prices[i])
        //Shares held,还有一次交易机会
        dp1[1][i] = Math.max(dp1[1][i - 1], dp2[0][i - 1] - prices[i])
        //No shares held,还有两次交易机会
        dp2[0][i] = Math.max(dp2[0][i - 1], prices[i] + dp1[0][i - 1]) 
        //No shares held,还有一次交易机会
        dp2[1][i] = Math.max(dp2[1][i - 1], prices[i] + dp1[1][i - 1])
    }
    
    return dp2[1][prices.length - 1]
};

188. The best time to buy and sell stocks IV (difficult)

Original question

Given an array, its i-th element is the price of a given stock on day I.

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 shares before you buy again).

Example 1:

Input: [2,4,1], k = 2
Output: 2
Explanation: buy on the first day (stock price = 2) and sell on the second day (stock price = 4). The exchange will get profit = 4-2 = 2.

Example 2:

Input: [3,2,6,5,0,3], k = 2
Output: 7
Explanation: buy on the second day (stock price = 2) and sell on the third day (stock price = 6). The exchange will get profit = 6-2 = 4.
     Then, buy on day 5 (stock price = 0) and sell on day 6 (stock price = 3), and the exchange will get profit = 3-0 = 3.

thinking

This question is the derivation of 123 questions. In the leetcode use case, there will bekToo large, resulting indpArray is too large, causing memory overflow.

Count RegnArray of, at mostn/2Sokgreater thann/2, we can treat this question as question 122 without limiting the number of transactions.

code


/**
 * @param {number} k
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(k, prices) {
    if (prices.length === 0 || prices.length === 1) {
        return 0
    }
    
    if (k === 0) {
        return 0
    }
    
    if (k > prices.length / 2) {
        k = -1
    }
    
    const dp1 = []
    const dp2 = []
    
    if (k == -1) {
        dp1[0] = -prices[0]
        dp2[0] = 0
    } else {
        for (let i = 0; i < k; i++) {
            dp1.push([-prices[0]])
            dp2.push([0])
        }
    }
    
    for (let i = 1; i < prices.length; i++) {
        if (k === -1) {
            dp1[i] = Math.max(dp1[i - 1], dp2[i - 1] - prices[i])
            dp2[i] = Math.max(dp2[i - 1], prices[i] + dp1[i - 1])
        } else {
            for (let j = 0; j < k; j++) {
                if (j === 0) {
                    dp1[j][i] = Math.max(dp1[j][i - 1], -prices[i]) 
                } else {
                    dp1[j][i] = Math.max(dp1[j][i - 1], dp2[j - 1][i - 1] - prices[i])
                }
                dp2[j][i] = Math.max(dp2[j][i - 1], prices[i] + dp1[j][i - 1]) 
                dp2[j][i] = Math.max(dp2[j][i - 1], prices[i] + dp1[j][i - 1])
            }
        }
    }
    
    if (k === -1) {
        return dp2[prices.length - 1]
    } else {
        return dp2[k - 1][prices.length - 1]
    }
};

QA

Q: today’s optimal solution is based on the previous day’s optimal solution. Can it guarantee the global optimal?

A: We can think of each day as the last. On the last day, our earnings are based on two possibilities. The first possibility is that we didn’t have a stock on the last day,
Because it’s the last day, we can’t buy stocks either. We can only maintain the earnings of the previous day. The second possibility is that at the end of the day, we happen to have stocks in our hands. We can only choose to sell them. The value of our earnings depends onShare price of the dayas well asPurchase price (the optimal value of holding shares), the share price of the day is certain and affirmative, ifPurchase priceIt’s not the optimal value. We can’t get the maximum value of income.

reference resources

[Most consistent ways of dealing with the series of stock problems
](https://leetcode.com/problems…

Recommended Today

SDS of redis data structure

SDS(simple dynamic string), simple dynamic string. S and it’s called hacking string. Where hack is stored is the length of the string and the remaining space in SDS. The implementation of SDS insds.cIn the middle. C language string uses a character array of length N + 1 to represent the string of length N, and […]