[rookie training] 714 The best time to buy and sell stocks includes handling charges

Posted by ruddyu78 on Tue, 08 Mar 2022 00:22:25 +0100

Title Description:

Given an integer array prices, where the i-th element represents the stock price on the i-th day; The nonnegative integer fee represents the handling fee for trading stocks.
You can complete transactions indefinitely, but you need to pay a handling fee for each transaction. If you have bought a stock, you can't continue to buy it until you sell it.
Returns the maximum profit.

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

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

be careful:
0 < prices.length <= 50000.
0 < prices[i] < 50000.
0 <= fee < 50000.

Problem solving ideas:

Method 1: using the same idea as 309, when it is on day i, there are two states: holding shares and not holding shares. So we just need to traverse the array and maintain these two states. The situation of not holding shares on the last day is the maximum profit.

Method 2: greedy algorithm. In method 1, we put the operation of paying the handling fee into consideration when selling stocks, and we change our way of thinking. Whenever we buy a stock, we pay the handling fee. Isn't it that we take price [i] + fee as the standard of whether we buy or not, so we can use the greedy algorithm.
But as we all know, greed is a local optimum every time. How can I make it a global optimum? Here, we offer the possibility to make it go back. That is, when using greed, we see that it is bigger than buying and then sell, but it may sell more the next day. How can we avoid this situation? We might as well give us the evaluation standard of the price on the day of selling after selling, that is, give us the opportunity to repent,
In this way, if the next day is more expensive than that of the same day, we will add the difference between the next day and that day to the maximum profit. In this way, we will not sell the stock on the same day and sell the stock on the next day. See the code note for details.

code:

public class LC714 {
    //Method 1: the idea is similar to 309 The best time to buy and sell stocks includes the freezing period
    //Time complexity O(n) space complexity O(n)
    //dp, for the end of day i, there are only two situations: holding stocks and not holding stocks
    public int maxProfit(int[] prices, int fee) {
        int ansProfit = 0;
        //The first dimension represents the day. The second dimension 0 represents not holding stocks and 1 represents holding stocks
        //The dp array stores the maximum profit at the end of the day
        int[][] dp = new int[prices.length + 10][2];
        //starting point:
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for (int i = 1;i < prices.length; i++){
            //Shares held at the end of day i
            //1.i-1 days
            //2. Do not hold on day i-1 and buy on day i
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0] - prices[i]);

            //No shares held at the end of day i
            //1.i-1 days do not hold
            //2. Held on day i-1 and sold on day i
            dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1] + prices[i] - fee);
        }
        //On the last day, the maximum profit must be the case of not holding shares
        ansProfit = dp[prices.length-1][0];
        return ansProfit;
    }

    //Method 2: greedy algorithm. Let's change our thinking and pay the handling fee when we sell to pay the handling fee when we buy
    //When we sell a stock, we immediately get the right to buy a stock at the same price without handling charges.
    //Time complexity O(n) space complexity O(1)
    public int maxProfit1(int[] prices, int fee) {
        int ansProfit = 0;
        //spend means the lowest purchase price if you own a stock on the premise of maximum return.
        int spend = prices[0] + fee;
        for (int i = 1; i < prices.length;i++){
            if (prices[i] > spend){
                ansProfit += (prices[i] - spend);
                //If the price of j is higher the next day, we will get prices[j] - prices[i]
                //In this way, we will not carry out any operation on this day and sell stocks the next day.
                //In this way, we transform the local optimal solution into the global optimal solution
                spend = prices[i];
            }
            //If the current day is cheaper than the previously assumed buying day, we will update the buying time and cost
            else if (prices[i] + fee < spend){
                spend = prices[i] + fee;
            }
        }
        return ansProfit;
    }


    public static void main(String[] args) {
        LC714 obj = new LC714();
        System.out.println(obj.maxProfit1(new int[]{1,3,7,5,10,3}, 3));
    }
}

Topics: leetcode