LeetCode 155: Min Stack

link

Top of the stack also keeps current minimum.

OperationTimeSpace
__init__\mathcal{O}(1)\mathcal{O}(1)
push\mathcal{O}(1)\mathcal{O}(1)
pop\mathcal{O}(1)\mathcal{O}(1)
top\mathcal{O}(1)\mathcal{O}(1)
getMin\mathcal{O}(1)\mathcal{O}(1)
class MinStack:

    def __init__(self):
        self.stack = []

    def push(self, val: int) -> None:
        curr_min = self.stack[-1][1] if self.stack else float("inf")
        self.stack.append((val, min(curr_min, val)))

    def pop(self) -> None:
        self.stack.pop()

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

    def getMin(self) -> int:
        return self.stack[-1][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()

Instead of keeping min per value, we can use a separate stack for mins. This way we need space for unique mins only.

class MinStack:

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

    def push(self, val: int) -> None:
        self.val_stack.append(val)
        if not self.min_stack or val < self.min_stack[-1][0]:
            self.min_stack.append( [val, 1] )
            return
        
        if val > self.min_stack[-1][0]:
            return
        
        # val == min
        self.min_stack[-1][1] += 1

    def pop(self) -> None:
        v = self.val_stack.pop()
        if v == self.min_stack[-1][0]:
            self.min_stack[-1][1] -= 1

        if self.min_stack[-1][1] == 0:
            self.min_stack.pop()

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

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


# 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()

Leave a comment