[Rookie Training] Sword refers to Offer 63. The maximum profit of stocks

Title description:

Assuming that the price of a certain stock is stored in an array in chronological order, what is the maximum profit that can be obtained from buying and selling the stock at one time?

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.

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

Restrictions:
0 <= array length <= 10^5

Source: LeetCode (LeetCode)
Link: https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof The
copyright is owned by LeetCode . For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.

Problem-solving ideas:

Three methods are adopted: the
first is direct violence, setting a variable to record the maximum value, and initializing it to 0. For example, on the ith day, if the price of a certain day after that day is greater than the price on the ith day, sell, and then compare and update with the maximum value. The time complexity and space complexity of this method are relatively large, and the time complexity is O(n²)

The second method is to use techniques. In order to obtain the maximum benefit, we will buy when the current day's price is the smallest, and then sell when the price is higher than this. After considering this point, the question arises. How can we ensure that we get the best benefit in the end? We can create two variables, one is used to record the current day and the lowest price before, and the other is used to record the current day's best interest. There are two situations on a certain day:
(1) If today's price is lower than the lowest price, it means that it cannot be transferred today, but it may make more profit in the future, so update the lowest price.
(2) If today's price is higher than the lowest price, it means that it is profitable today. We will sell it to see if the benefit we get is greater than the current maximum benefit. If it is greater than the current maximum benefit, the maximum benefit will be updated, not greater than no. Any operation.
In this way, after executing the loop, the biggest benefit is the answer.
Time complexity is O(n)

The third is to use the idea of ​​dp, dp[i] is used to store the maximum benefit that can be obtained on the i-th day. On the jth day,
(1) If the price on the jth day is less than the lowest price, update the lowest price. The best profit is the same as the j-1 day
(2) If the price on the j day is greater than the lowest price, it is profitable. The profit obtained after selling is compared with yesterday’s best profit, which is dp[j-1] .
The time complexity is slightly higher than that of the second method. The overall idea is the same as that of the second method, except that a dp idea is added to the second method. If the problem is to get the best daily benefit, this method can solve this problem.

Code:

public class jianzhi_Offer_63 {
    
    
    //方法一:暴力,直接把所有情况算出进行比较,取最大。时间空间使用严重 时间复杂度O(n²)
    public int maxProfit(int[] prices) {
    
    
        int maxprice = 0;
        for (int i = 0; i < prices.length; i++){
    
    
            for (int j = i; j < prices.length; j++){
    
    
                int tmp = prices[j] - prices[i];
                maxprice = maxprice < tmp ? tmp:maxprice;
            }
        }
        return maxprice;
    }
    //方法2:我们只需要在当前最低价买入,然后想怎样让股票利益最大化,那不妨每天都卖一次去和当前最大利益比较。
    //如果今天的价格是历史最低,说明转不了,后面有可能赚的比现在多。那我们只需要将记录最低价的变量重新赋值,表示从当前最低价买入
    //如果今天价格比最低价高,说明今天能赚钱,那我们就卖出来看看是否比当前最大利益大。
    //时间复杂度O(n)
    public int maxProfit1(int[] prices) {
    
    
        if(prices.length == 0 ||prices.length == 1){
    
    
            return 0;
        }
        if(prices.length == 2){
    
    
            return prices[0] > prices[1] ? 0 : (prices[1] - prices[0]);
        }
        int maxprice = 0;
        int min = prices[0];
        for (int i = 1; i < prices.length; i++){
    
    
            if(prices[i] < min){
    
    
                min = prices[i];
            }else {
    
    
                maxprice = maxprice < (prices[i] - min) ? (prices[i] - min) : maxprice;
            }
        }
        return maxprice;
    }

    //方法三:使用dp数组,dp[i]存取,到目前第i天的最大利益。
    public int maxProfit2(int[] prices) {
    
    
        if(prices.length == 0 ||prices.length == 1){
    
    
            return 0;
        }
        if(prices.length == 2){
    
    
            return prices[0] > prices[1] ? 0 : (prices[1] - prices[0]);
        }

        int[] dp = new int[prices.length];
        //只有一个数的时候,无利可图
        dp[0] = 0;
        int min = prices[0];
        for (int i = 1; i < prices.length; i++){
    
    
            if(prices[i] < min){
    
    
                min = prices[i];
                dp[i] = dp[i - 1];
            }else {
    
    
                //比较前一天的最大利益和今天卖出的利益哪一个大,从而得到当前最大利益
                dp[i] = Math.max(prices[i] - min, dp[i-1]);
            }
        }
        //最后一天一定是最大利益
        return dp[dp.length - 1];
    }

    public static void main(String[] args) {
    
    
        jianzhi_Offer_63 obj = new jianzhi_Offer_63();

        int[] prices = new int[]{
    
    7,1,5,3,6,4};
        System.out.println(obj.maxProfit2(prices));
    }
}

Guess you like

Origin blog.csdn.net/Puppet__/article/details/115052967