- The problem is "Best Time to Buy and Sell Stock", which is problem number 121 on LeetCode.
- The difficulty level of this problem is Easy.
- We are given an array where the ith element is the price of a given stock on day i.
- We need to find the maximum profit. We can complete at most one transaction (i.e., buy one and sell one share of the stock).
- We must buy before we can sell.
Input: prices = [7,1,5,3,6,4]
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.
Questions that can be asked to the interviewer:
- Can the input array be empty?
- Can the input array have only one element?
- What should be returned if no profit can be made?
- An edge case in this problem could be when the stock price continually decreases throughout the period. In this case, no profit can be made, so the function should return 0.
- Another edge case would be when the input array is empty or contains only one element. Again, the function should return 0 in these cases.
- A brute force solution would be to calculate the profit for every pair of prices and keep track of the maximum profit. This approach would take O(n^2) time, where n is the number of days.
- A more efficient solution would be to iterate over the prices once, keeping track of the minimum price and the maximum profit so far. This approach would take O(n) time.
My approach is the efficient one:
- I'll start by initializing min_price as the first price and max_profit as 0.
- Then I'll iterate over the prices. For each price:If it's less than min_price, I'll update min_price.
- Otherwise, I'll calculate the profit by subtracting min_price from the current price, and if it's more than max_profit, I'll update max_profit.
- Finally, I'll return max_profit.
def maxProfit(prices):
? ? min_price = prices[0]
? ? max_profit = 0
? ? for price in prices:
? ? ? ? if price < min_price:
? ? ? ? ? ? min_price = price
? ? ? ? else:
? ? ? ? ? ? profit = price - min_price
? ? ? ? ? ? if profit > max_profit:
? ? ? ? ? ? ? ? max_profit = profit
? ? return max_profit
An explanation for a non-programmer:
- Imagine you're a stock trader, and you're given a list of the price of a particular stock for the next few days.
- Your goal is to make the most money by buying and selling the stock once. You must buy before you sell.
- Here's how you could do it: On the first day, note the price. This is the cheapest price you've seen so far.
- On each subsequent day, do one of two things: If the stock is cheaper than the cheapest price you've seen so far, note this new price. If the stock is more expensive, calculate how much money you would make if you bought the stock at the cheapest price you've seen and sold it at the current price.
- Keep going like this, always keeping track of the cheapest price and the most money you could make. At the end of the list, the most money you've calculated is the most you could make.
Detailed explanation of the code:
- The function takes a list of prices as its argument.
- It initializes min_price as the first price in the list and max_profit as 0.
- It then goes through each price in the list.For each price, it checks if the price is less than min_price. If it is, it updates min_price with the current price.
- If the price is not less than min_price, it calculates the profit by subtracting min_price from the current price. If this profit is greater than max_profit, it updates max_profit with the new profit.
- Finally, after checking all the prices, it returns max_profit, which is the maximum profit that can be made.
The pattern that this problem follows:
- This problem is a classic example of an optimization problem where you want to maximize or minimize a particular quantity - in this case, profit.
- The solution uses a technique known as "dynamic programming". In this technique, we solve a problem by breaking it down into smaller sub-problems and solving these sub-problems optimally to find the overall optimal solution. In this case, the sub-problems are finding the minimum price and the maximum profit for each price in the list.
- This particular pattern is often referred to as "max/min tracking", where you track and update the maximum or minimum value as you iterate through a list.
The time complexity of this algorithm is O(n), where n is the number of days (or the length of the prices list). This is because we iterate over the list once, performing constant-time operations for each price in the list. Thus, the time complexity is linear in the size of the input.
The space complexity is O(1), constant, because we only use two variables (min_price and max_profit) to keep track of the minimum price and maximum profit. The space usage does not increase with the size of the input.
Points to remember for the future:
- This problem is a classic example of dynamic programming, where we break down a larger problem into smaller sub-problems (in this case, finding the minimum price and maximum profit for each price in the list).
- Remember the pattern of iterating through the list while keeping track of the minimum price and maximum profit.
- Remember that you need to buy before you can sell, so the minimum price must always come from the days before the current day.
Line by line code explanation with sample data:
Consider prices = [7, 1, 5, 3, 6, 4]:
- Initialize min_price as float('inf'), which acts as an initial placeholder for the minimum price, and max_profit as 0.
- For the first iteration (price is 7), 7 is not less than min_price, and 7 - min_price (which is 0) is not greater than max_profit, so no changes are made.
- On the second iteration (price is 1), 1 is less than min_price, so min_price is updated to 1.
- On the third iteration (price is 5), 5 is not less than min_price (which is 1), and 5 - min_price (which is 4) is greater than max_profit (which is 0), so max_profit is updated to 4.
- The process continues in this manner, updating min_price when a lower price is found and updating max_profit when a higher profit is found.
- At the end of all iterations, max_profit is returned, which in this example would be 5 (buy at 1 and sell at 6).
Key syntax for this solution:
- The min() function is used to update the minimum price: min_price = min(min_price, price)
- The max() function is used to update the maximum profit: max_profit = max(max_profit, price - min_price)
- A for loop is used to iterate over the prices: for price in prices.
Sure, here are some similar problems from LeetCode:
- Best Time to Buy and Sell Stock II (LeetCode 122 - Easy): In this problem, unlike the first one, you're allowed to make as many transactions as you like (i.e., buy one and sell one share of the stock multiple times). The challenge here is to figure out the maximum profit you can achieve.
- Best Time to Buy and Sell Stock III (LeetCode 123 - Hard): This problem asks you to find the maximum profit you can achieve with at most two transactions. This adds another layer of complexity to the problem.
- Best Time to Buy and Sell Stock IV (LeetCode 188 - Hard): In this version of the problem, you're given an integer 'k' and you need to figure out the maximum profit you can achieve with at most 'k' transactions.
- Best Time to Buy and Sell Stock with Cooldown (LeetCode 309 - Medium): This problem adds a "cooldown" requirement, where after selling a stock, you cannot buy another one for the next day.
- Best Time to Buy and Sell Stock with Transaction Fee (LeetCode 714 - Medium): In this problem, a transaction fee is added. You need to calculate the maximum profit you can achieve, keeping in mind that you have to pay a fee every time you sell a stock.