less than 1 minute read

Problem Statement

problem

Intuition

My initial thoughts are to maintain two stacks: one for the main elements and another for the minimum elements seen so far.

Approach

I will use two stacks, main_stack and min_stack. When pushing a value onto the main stack, I will also push the current minimum onto the min_stack if it is the first element or if the new value is smaller than the current minimum. When popping elements, I will ensure that both stacks are updated accordingly. The top and getMin operations can then be performed by looking at the top elements of their respective stacks.

Complexity

  • Time complexity: Push: O(1) Pop: O(1) Top: O(1) getMin: O(1)

  • Space complexity: O(n), where n is the number of elements in the stack.

Code

class MinStack:

    def __init__(self):
        self.main_stack = []
        self.min_stack = []

    def push(self, val: int) -> None:
        self.main_stack.append(val)
        if not self.min_stack or self.min_stack[-1] > val:
            self.min_stack.append(val)
        else:
            self.min_stack.append(self.min_stack[-1])

    def pop(self) -> None:
        self.main_stack.pop()
        self.min_stack.pop()

    def top(self) -> int:
        return self.main_stack[-1]

    def getMin(self) -> int:
        return self.min_stack[-1]
        


# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()