def solve(self):
        """Solve the problem

        Note: O(n) (runtime) since every bar is pushed and popped only once.

        Args:

        Returns:
            integer

        Raises:
            None
        """
        # stack to store the indices
        stack = Stack()

        max_area = 0
        index = 0

        while index < len(self.input_list):
            # If this bar is higher than the bar on top stack, push it to stack
            if len(stack) == 0 or self.input_list[
                    stack.peek()] <= self.input_list[index]:
                stack.push(index)
                index = index + 1

            # If this bar is lower than top of stack, then calculate area of rectangle with
            # stack top as the smallest (or minimum # height) bar.'i' is 'right index' for
            # the top and element before top in stack is 'left index'
            else:
                top_index = stack.pop()

                # Calculate the area with histogram[top_of_stack] stack as smallest bar
                area = (self.input_list[top_index] *
                        ((index - stack.peek() - 1) if stack else index))

                max_area = max(area, max_area)

        # Now pop the remaining bars from  stack and calculate area with
        # every popped bar as the smallest bar
        while stack:
            # pop the top
            top_index = stack.pop()

            # Calculate the area with
            # histogram[top_of_stack]
            # stack as smallest bar
            area = (self.input_list[top_index] *
                    ((index - stack.peek() - 1) if stack else index))

            # update max area, if needed
            max_area = max(max_area, area)

        return max_area
Example #2
0
    def solve(self):
        """Solve the problem

        Note: O(n logn) (runtime) and O(n) (Space) works by using a stack to store the elements in the order.
        Then, when the right subtree element is reached, it will pop the left subtree elements and then the root is
        set.

        Args:

        Returns:
            boolean

        Raises:
            None
        """
        print("Solving {} problem ...".format(self.PROBLEM_NAME))

        value_stack = Stack()

        root = -sys.maxsize

        for value in self.input_list:
            # If we find a node which is on the right side
            # and smaller than root, return False
            if value < root:
                return False

            while len(value_stack) > 0 and value_stack.peek() < value:
                root = value_stack.pop()

            # If we find a node who is on the right side
            # and greater than root, add to the stack
            value_stack.push(value)

        return True
Example #3
0
class MinStack(Problem):
    """
    Min Stack
    """
    PROBLEM_NAME = "MinStack"

    def __init__(self):
        """Min Stack

        Args:

        Returns:
            None

        Raises:
            None
        """
        super().__init__(self.PROBLEM_NAME)
        self.input_stack = Stack()
        self.min_stack = Stack()

    def solve(self):
        """Solve the problem

        Args:

        Returns:
            None

        Raises:
            None
        """
        pass

    def push(self, data):
        """Push an element to the stack

        Args:

        Returns:
            None

        Raises:
            None
        """
        self.input_stack.push(data)

        if self.min_stack.peek() is None or data < self.min_stack.peek():
            self.min_stack.push(data)

    def pop(self):
        """Pops the element from the stack

        Args:

        Returns:
            data

        Raises:
            None
        """
        data = self.input_stack.pop()

        if data == self.min_stack.peek():
            self.min_stack.pop()

        return data

    def top(self):
        """Return the top element from the input stack

        Args:

        Returns:
            data

        Raises:
            None
        """
        return self.input_stack.peek()

    def get_min(self):
        """Return the min element from the min stack

        Args:

        Returns:
            data

        Raises:
            None
        """
        return self.min_stack.peek()