DEV Community

Shailesh Kumar
Shailesh Kumar

Posted on

Leetcode September Day18

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 -

  1. New element is greater than our current_min, in that case we update our max_profit.
  2. 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)