Skip to content

121. Best Time to Buy and Sell Stock

Problem

You are given an array prices where prices[i] is the price of a given stock on the ith day.

You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock.

Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0.

Example 1:

Input: prices = [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.

Solve

Brute force

O(n ** 2)

  • A quick n**2 answer
  • Which don’t care about how input prices work
    • We checking all possible buy time (which cost O(n) time)
    • each time, we find the best time to sell stock (which also cost O(n) time)
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if len(prices) == 1:
            return 0

        max_price = 0
        for i in range(len(prices)):
            for j in range(i+1, len(prices)):
                if max_price >= prices[j] - prices[i]:
                    continue
                max_price = prices[j] - prices[i]

        return max_price

Optimizing

O(n)

  • We can optimize this by try find the max price of prices[i+1: len(prices)] immediately. We could use a Dynamic programming for storing all Maximum value of prices[i+1: len(prices)]
    # TODO
    

Or calculating it on the fly in the same loop that checking all possible stock buy times.

In final implementation, I instead do a reverse job, where I checking all possible stock sell time (which between [1 .. len(prices) - 1]).

  • For this case, we instead find min price or prices[0: j]. Keeping track of it in curr_min_price variable.
  • This just update the stock best max_price from 1 to n. Using this formula
    max_price = prices[index] - curr_min_price
    

Final implementation

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if len(prices) == 1:
            return 0
        curr_min_price = prices[0] # keep track of the min of value price[0:index-1]
        max_price = 0
        for index, value in enumerate(prices):
            if index == 0:
                continue
            if max_price < prices[index] - curr_min_price:
                max_price = prices[index] - curr_min_price
            if curr_min_price > prices[index]:
                curr_min_price = prices[index]

        return max_price

Last update : September 17, 2023
Created : August 16, 2023