Buy and sell stock once
1. Problem statement
Given a list of prices for a stock over the past N days (one price per day), determine the optimum days to buy and sell the stock once to maximize profit (Aziz et al., 2018, p. 51).
1.1. Inputs and outputs
- Input: list of stock prices (positive numbers)
- Output: day to buy the stock, day to sell the stock, and the realized profit margin
2. Insights
Simply taking the minimum and maximum values of the entire range, and comparing
these two numbers, won't work. Example: [10, 5]
. Here the only possible buy
and sale is to buy at price 10
and sell on the next day at price 5
. But
doing so would result in a loss. If the price is decreasing each day, then
every possible buy/sell combination will result in a loss. In this situation
the algorithm should not recommend a buy/sell transaction at all (do nothing).
Here's another example: [10, 9, 8, 1, 2, 6]
. Here the maximum possible profit
is to buy at 1
and sell at 6
, for a profit margin of 5
. The minimum and
maximum prices are 1
and 10
, which are interesting but don't give us the
answer.
3. Solutions
3.1. Brute force
Compare every number in the list with every other number. That is, compute every possible combinationa of buy/sell dates, and just return the best (max profit) dates found.
The time complexity is \(O(n^2)\) where \(n\) is the length of the list of prices.
3.2. Optimal
For the optimal solution, the key is to pretend to sell on that day, using the
minimum price found in the previous days as the buying point. The trick here is
that the previous minimum price calculation can be updated on each iteration
with just a single min()
comparison.
The time complexity is \(O(n)\).
3.2.1. As maximum subarray
As Cormen et al. (2009, p. 69) point out, if we look at stock prices not as the prices themselves but as changes in price on each day, then the problem of finding the best buy/sell dates is the same as finding the maximum subarray.
The only annoying thing though, is that the indices are off by 1 (either the
buy or sell date) because we lose 1 element to construct the changes
array
(the transformation of data from the list of prices to the list of changes is
lossy). Still, the maximum achievable profit is accurate, and agrees with our
optimal
solution.