Link to the original text: he Xiaodong’s blog
The best time to buy and sell stocks
Given an array, its I th element is the price of a given stock on day I.
If you are allowed to complete at most one transaction (that is, to buy and sell a stock once), design an algorithm to calculate the maximum profit you can make.
Note: you can’t sell stocks 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), with 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 can't sell the stock before you buy it.
Example 2:
Input: [7,6,4,3,1]
Output: 0
Explanation: in this case, the transaction is not completed, so the maximum profit is 0.
Source: leetcode
Link: https://leetcode-cn.com/probl…
Solutions 1 – exhaustive
Enumerate the difference between two adjacent elements and solve the problem violently.
As a result, it will time out when there is a large amount of data, and there are too many factorials.
code
class Solution {
/**
* @param Integer[] $prices
* @return Integer
*/
function maxProfit($prices) {
$count = count($prices);
if ($count < 2) {
return 0;
}
//It is possible not to trade, so the initial value of the result is set to 0
$res = 0;
for ($i = 0; $i < $count - 1; $i++) {
for ($j = $i + 1; $j < $count; $j++) {
$res = max($res, $prices[$j] - $prices[$i]);
}
}
return $res;
}
}
The best edition
Record the minimum value in advance, and omit the inner loop.
class Solution {
/**
* @param Integer[] $prices
* @return Integer
*/
function maxProfit($prices) {
$count = count($prices);
if ($count < 2) {
return 0;
}
$res = 0;
//Represents the minimum value before the current position
$minVal = $prices[0];
//Note: this starts with 1
for ($i = 1; $i < $count; $i++) {
$res = max($res, $prices[$i] - $minVal);
$minVal = min($minVal, $prices[$i]);
}
return $res;
}
}
Solution 2 – dynamic programming
Set statusdp[i][j]
On the day of index I, the maximum profit obtained when the user’s holding status is J
J has only two values: 0 means no holding (especially refers to the non holding state after selling the shares), and 1 is the holding shares
The state transition equation is as follows
dp[i][0]
How to transfer?
dp[i - 1][0]
Of course, it can be transferred from yesterday without holding shares, which means that nothing will be operated from yesterday to todaydp[i - 1][1] + prices[i]
Yesterday, I sold the stock on the day of index I, and the status changed from 1 to 0. At this time, I sold the stock, so I added the stock price of that day
To sum up:dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])
;
How does DPI transfer?
dp[i - 1][1]
: yesterday’s shareholding, today’s nothing operation, of course, can be transferred from yesterday’s shareholding-prices[i]
Note: status 1 cannot be derived from status 0, because in fact, status 0 specifically refers to “the state of not holding shares after selling stocks”, and the title can only be traded once, so it cannot be addeddp[i - 1][0]
So,-prices[i]
That is, on the day the index is I, the proceeds from the buy operation
To sum up:dp[i][1] = max(dp[i - 1][1], -prices[i])
;
Initial value:
No shares on day 0, obviouslydp[0][0] = 0
;
Day 0, obviouslydp[0][1] = -prices[0]
code
class Solution {
/**
* @param Integer[] $prices
* @return Integer
*/
function maxProfit($prices) {
$count = count($prices);
if ($count < 2) {
return 0;
}
$res = 0;
//0: the maximum profit that users can get if they don't hold shares in their hands, especially when they sell stocks
//1: the maximum profit that users can get by holding shares in their hands
//Note: because the title can only be traded once, the status can only be from 1 to 0, not from 0 to 1
$dp = [];
$dp[0][0] = 0;
$dp[0][1] = -$prices[0];
for ($i = 1; $i < $count; $i++) {
$dp[$i][0] = max($dp[$i - 1][0], $dp[$i - 1][1] + $prices[$i]);
$dp[$i][1] = max($dp[$i - 1][1], -$prices[$i]);
}
return $dp[$count - 1][0];
//One dimensional array optimization
// $dp = [];
// $dp[0] = 0;
// $dp[1] = -$prices[0];
// for ($i = 1; $i < $count; $i++) {
// $dp[0] = max($dp[0], $dp[1] + $prices[$i]);
// $dp[1] = max($dp[1], -$prices[$i]);
// }
// return $dp[0];
}
}
Solution 3 – differential array
Differential arrayThe value of the sum of the successive subintervals of the original stock price array is exactly the price difference of the original stock price array for one transaction (back front)
For example: for arrays1 6 2 8
, represents the daily price of the stock
Define a conversion rule. The price of the current day minus the price of the previous day. Since there is no previous day on the first day, it is specified as 0 to represent no operation
The array is converted to0 6-1 2-6 8-2
That is to say0 5 -4 6
。 Now the meaning of the array is the change of the stock relative to the previous day
Now we just need to find out what the continuous sum is, that is to say, 53 questions
Continuous sum, such as the sum of the corresponding day 3 to day 6, the corresponding buy and sell is actually the second day of buying and the sixth day of selling
Therefore, we can find the sum of the largest continuous subsequences on the difference group
code
class Solution {
/**
* @param Integer[] $prices
* @return Integer
*/
function maxProfit($prices) {
$count = count($prices);
if ($count < 2) {
return 0;
}
$dp = 0;
$max = 0;
for ($i = 1; $i < $count; $i++) {
//Cumulative earnings on adjacent dates (difference)
$num = $prices[$i] - $prices[$i - 1];
$dp = max($dp + $num, $num);
$max = max($max, $dp);
}
return $max;
}
}
Reference link
- The best time to buy and sell stocks
Finally, the best choice for small and medium-sized enterprises to go to the cloud is to buy a full range of Alibaba cloud products