Problem -
Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.
Note that you cannot sell a stock before you buy one.
Example
"""
Input: [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.
Not 7-1 = 6, as selling price needs to be larger than buying price.
"""
Solution
Approach - Using deque. Using deque to keep track of maximum price to the right. We then iterate again and update the maximum profit.
TC = O(nlogn)
class Solution:
def maxProfit(self, prices: List[int]) -> int:
# we can use stack based approach
stack = []
ans = [0] * len(prices)
for i in range(len(prices)-1, -1, -1):
if i == len(prices)-1:
stack.append(prices[i])
continue
while True:
if prices[i] > stack[-1]:
stack.pop()
if len(stack) == 0:
stack.append(prices[i])
ans[i] = prices[i]
break
else:
stack.append(prices[i])
ans[i] = stack[0]
break
res = 0
for a, m in zip(ans, prices):
res = max(res, a - m)
return res
We can still optimize this approach. For each smaller element we are interested in the greater elements to the right. So, while iterating the array, we can arrive at two possibilities -
- New element is greater than our current_min, in that case we update our max_profit.
- New element is smaller than our current_min, in that case we update our current_min. Solution
class Solution:
def maxProfit(self, prices: List[int]) -> int:
current_min = float('inf')
max_profit = 0
for price in prices:
if price < current_min:
current_min = price
else:
max_profit = max(max_profit, price - current_min)
return max_profit
Edit -
Was trying to have some fun and came up with this one liner
class Solution:
def maxProfit(self, prices: List[int]) -> int:
return reduce(lambda p,c: (max(p[0], c - p[-1]) , min(p[-1], c)) if type(p) == type((1,2,)) else (0, c), [0] + prices)[0] if prices else 0
Top comments (0)