# subject

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, to buy and sell a stock once), design an algorithm to calculate the maximum profit you can obtain. Note: you can't sell shares before you buy them

Source: LeetCode

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

Copyright belongs to the network. For commercial reprint, please contact the official authorization. For non-commercial reprint, please indicate the source.

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; at the same time, you cannot sell the stock before buying. Input: [7,6,4,3,1] Output: 0 Explanation: in this case, there is no transaction completed, so the maximum profit is 0.

# answer

## Method 1:

I just started to analyze this question, and I think it's such a feature

- Find the maximum difference between two numbers in the array
- The number of the back side is larger than the number of the front side

The direct idea is to loop each element, then take the elements in front of this element and the number one by one to find the maximum value, and then judge whether it is greater than 0 when returning

class Solution { public: int maxProfit(vector<int>& prices) { if (prices.empty() || prices.size() == 1) { return 0; } int res_max = prices[1] - prices[0]; for (int i = 2; i <prices.size(); ++i) { for (int j = 0; j < i; ++j) { if (prices[i] - prices[j] > res_max) { res_max = prices[i] -prices[j]; } } } return res_max > 0 ? res_max : 0; } };

Once running, beyond the time limit, it seems that violent methods are becoming more and more useless.

But I don't want to give up this idea. I think it's very reasonable. Generally speaking, the first reaction is that everyone thinks so. In order to get the submission result, I think the violence method must have calculated a lot of things. Let's try to optimize it.

- The first is to set the default maximum value to 0, so that when you do not need to return, you can perform a ternary operation every time, and the data in the middle will not enter the if if if if it encounters a negative number.
- The second reason is that each element will complete the previous calculation of the difference value. When calculating the next element, if the next element is smaller than this element, there is no need to calculate. If the maximum difference value of this element position changes, then the previous element is larger than it, and the difference value must be larger. Then it must be calculated in advance. This position The calculation of is also unnecessary. Adding this judgment should reduce many cycles.

class Solution { public: int maxProfit(vector<int>& prices) { if (prices.empty() || prices.size() == 1) { return 0; } int res_max = 0; for (int i = 1; i < prices.size(); ++i) { ///Do not calculate in this case, because if i + 1 produces the maximum difference, ///So i must have a bigger difference. i must have finished the calculation ahead of time if (prices[i] <= prices[i - 1]) { continue; } for (int j = 0; j < i; ++j) { if (prices[i] - prices[j] > res_max) { res_max = prices[i] -prices[j]; } } } return res_max; } };

Sure enough, the program did not time out.

## Method 2:

I have another plan to see if it can be done in a cycle.

- Mark a buying location, a selling location and let them move
- The selling position must be behind the buying position
- If there is a value smaller than the buy point, then the buy point should be moved
- If there is a value greater than the selling point, the selling point should be moved
- You can find the maximum value by calculating the difference between the buying point and the selling point every time

class Solution { public: int maxProfit(vector<int>& prices) { if (prices.empty() || prices.size() == 1) { return 0; } //Assume the position of the maximum difference f ﹣ n int res_max = prices[1] - prices[0]; int buy_index = 0, sell_index = 1; for (int i = 1; i < prices.size(); i++) { // If you find something smaller than buying something, you can buy it by mobile if (prices[buy_index] > prices[i]) { buy_index = i; } //If you find something bigger than the selling point, move the selling point if (prices[sell_index] <= prices[i]) { sell_index = i; } if (sell_index < buy_index) { //After the purchase point moves, the selling point also moves sell_index = buy_index; continue; } res_max = max(res_max, prices[sell_index] - prices[buy_index]); } return res_max; } };

## Method 3:

Look at the answers from other people's methods

The idea should be roughly the same as method 2, but more concise.

- Record the minimum value and update it as long as the minimum value changes.
- Each element is subtracted from the minimum. Compare sizes.

class Solution { public: int maxProfit(vector<int>& prices) { if (prices.empty() || prices.size() == 1) { return 0; } int res_max = 0; int min = prices[0]; //Record past minimum for (int i = 1; i < prices.size(); i++) { if (prices[i] > min) { res_max = max(res_max, prices[i] - min); } else { min = prices[i]; } } return res_max; } };