You are given an array prices
where prices[i]
is the price of a given stock on the ith
day.
Find the maximum profit you can achieve. You may complete at most two transactions.
Note: You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).
Example 1:
Input: prices = [3,3,5,0,0,3,1,4] Output: 6 Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3. Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.
Example 2:
Input: prices = [1,2,3,4,5] Output: 4 Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are engaging multiple transactions at the same time. You must sell before buying again.
Example 3:
Input: prices = [7,6,4,3,1] Output: 0 Explanation: In this case, no transaction is done, i.e. max profit = 0.
Constraints:
1 <= prices.length <= 105
0 <= prices[i] <= 105
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
To find the best possible profit from at most two trades, the most straightforward approach is to try every single possible combination of two trades. We'll simply divide the entire history of stock prices into two separate periods and find the best single trade we could have made in each period.
Here's how the algorithm would work step-by-step:
def maxProfit(prices):
number_of_days = len(prices)
if number_of_days < 2:
return 0
def max_profit_one_transaction(price_history):
if not price_history:
return 0
lowest_price_so_far = float('inf')
max_profit_found = 0
for current_price in price_history:
profit = current_price - lowest_price_so_far
max_profit_found = max(max_profit_found, profit)
lowest_price_so_far = min(lowest_price_so_far, current_price)
return max_profit_found
max_total_profit = 0
# The main loop iterates through every possible day to split the timeline into two periods.
for split_index in range(number_of_days + 1):
first_period_prices = prices[0:split_index]
second_period_prices = prices[split_index:number_of_days]
# We calculate the max profit for a single trade in the first period.
max_profit_first_period = max_profit_one_transaction(first_period_prices)
# Then, we do the same for the second period to find its best single trade profit.
max_profit_second_period = max_profit_one_transaction(second_period_prices)
# The total profit for this specific split is the sum of profits from both periods.
current_total_profit = max_profit_first_period + max_profit_second_period
max_total_profit = max(max_total_profit, current_total_profit)
return max_total_profit
Imagine you have to complete at most two round trips of buying and then selling a stock. The clever approach is to track the most money you could have after each of the four possible actions (your first buy, first sell, second buy, and second sell) as you go through the daily prices one by one.
Here's how the algorithm would work step-by-step:
def maxProfit(prices):
if not prices:
return 0
# Initialize states representing the max money after each of the four actions.
profit_after_first_buy = -prices[0]
profit_after_first_sell = 0
profit_after_second_buy = -prices[0]
profit_after_second_sell = 0
for current_price in prices:
# We want the smallest loss, so we choose the minimum of the previous state and buying now.
profit_after_first_buy = max(profit_after_first_buy, -current_price)
# For the first sale, we either stick with our previous best sale or sell today.
profit_after_first_sell = max(profit_after_first_sell, profit_after_first_buy + current_price)
# For the second buy, we use profits from the first sale to 'invest' in this new stock.
profit_after_second_buy = max(profit_after_second_buy, profit_after_first_sell - current_price)
# The final profit is the max of the previous best second sale or selling our second stock today.
profit_after_second_sell = max(profit_after_second_sell, profit_after_second_buy + current_price)
return profit_after_second_sell
Case | How to Handle |
---|---|
Empty input array | The profit is zero as no transactions can be made. |
Input array with only one element | The profit must be zero since a buy and a sell operation requires at least two days. |
Prices are in strictly decreasing order (e.g., [5, 4, 3, 2, 1]) | The maximum profit is zero because buying on any day and selling later will always result in a loss. |
Prices are in strictly increasing order (e.g., [1, 2, 3, 4, 5]) | The algorithm should correctly identify that two transactions are better than one, splitting the single long profit trend. |
All prices in the array are identical (e.g., [7, 7, 7, 7]) | The profit is zero as no profitable transaction is possible. |
The optimal solution involves only one transaction, not two | The algorithm must correctly determine that using only one of the two allowed transactions yields the maximum profit. |
Input array contains zero as a price | Zero is a valid price and should be handled like any other non-negative integer in profit calculations. |
Very large input array size (e.g., 10^5 elements) | The solution should be O(n) in time and O(1) in space to avoid timeout or memory limit errors. |