def nextGreaterElements(self, nums: List[int]) -> List[int]:
        """
        核心:
            1.单调栈
            2.利用取模运算(%)获得环形特效,解决环形数组
        """
        monotonous_stack = Stack()
        nums_len = len(nums)
        res_lis = [-1] * nums_len

        # 将 nums2 的所有元素,倒序入单调栈
        for i in range(nums_len * 2 - 1, -1, -1):
            index = i % nums_len
            # 1.维护单调栈
            while not monotonous_stack.is_empty(
            ) and nums[index] >= monotonous_stack.peek():
                monotonous_stack.pop()

            # 2.利用栈
            res_lis[index] = monotonous_stack.peek() if monotonous_stack.peek(
            ) is not None else -1

            # 3.单调栈入栈
            monotonous_stack.push(nums[index])
        return res_lis
class MyQueue:
    """核心:使用两个栈,分别主要用于入队、出队"""
    def __init__(self):
        self.s1 = Stack()  # 用于入队
        self.s2 = Stack()  # 用于出队

    def moves_items(self):
        """pop all items form s1 and push them to s2"""
        while not self.s1.is_empty():
            self.s2.push(self.s1.pop())

    def push(self, x: int) -> None:
        self.s1.push(x)

    def pop(self) -> int:
        if self.s2.is_empty():
            self.moves_items()
        return self.s2.pop()

    def peek(self) -> int:
        if self.s2.is_empty():
            self.moves_items()
        return self.s2.peek()

    def empty(self) -> bool:
        return self.s1.is_empty() and self.s2.is_empty()
コード例 #3
0
    def reverseStack(self, s: Stack) -> Stack:
        # 递归边界
        if s.is_empty() or s.size == 1:
            return s

        # 将底部元素移到顶部
        self.move_bottom_to_top(s)
        # 该栈 pop 出一个元素并记录在 top 中,形成子栈,并递归调用翻转方法
        top = s.pop()
        s = self.reverseStack(s)

        # 翻转后的子栈,push 原来的 top 元素
        s.push(top)
        return s
コード例 #4
0
    def nextGreaterElement(self, nums1: List[int],
                           nums2: List[int]) -> List[int]:
        """核心:单调栈"""
        monotonous_stack = Stack()  # 单调栈,单调递减
        memory_dic = {}

        # 将 nums2 的所有元素,倒序入单调栈
        for i in range(len(nums2) - 1, -1, -1):
            # 1.维护单调栈--[将单调栈中 <= 当前元素(nums2[i])的元素,全部 pop 出去]
            while not monotonous_stack.is_empty(
            ) and nums2[i] >= monotonous_stack.peek():
                monotonous_stack.pop()

            # 2.使用单调栈--[根据单调栈的栈顶元素(stack.peek()),获取值]
            memory_dic[nums2[i]] = -1 if monotonous_stack.is_empty(
            ) else monotonous_stack.peek()

            # 3.元素入栈
            monotonous_stack.push(nums2[i])
        return [memory_dic.get(item) for item in nums1]
    def largestRectangleArea(self, heights: List[int]) -> int:
        """
        单调栈(单增): 保持栈顶为当前栈最大元素
        我们在缓存数据的时候,是从左向右缓存的,
        我们计算出一个结果的顺序是从右向左的,并且计算完成以后我们就不再需要了,
        符合后进先出的特点。因此,我们需要的这个作为缓存的数据结构就是栈。
        """
        lis_len = len(heights)
        max_area = 0

        stack = Stack()

        for i in range(lis_len):
            while not stack.is_empty() and heights[i] < stack.peek()[1]:
                index, cur_height = stack.pop()

                # 处理相等的特殊情况
                while not stack.is_empty() and heights[i] == stack.peek():
                    stack.pop()

                if stack.is_empty():
                    cur_width = i
                else:
                    cur_width = i - stack.peek()[0] - 1

                max_area = max(max_area, cur_height * cur_width)
            stack.push([i, heights[i]])

        while not stack.is_empty():
            index, cur_height = stack.pop()

            while not stack.is_empty() and cur_height == stack.peek()[1]:
                stack.pop()

            if stack.is_empty():
                cur_width = lis_len
            else:
                cur_width = lis_len - stack.peek()[0] - 1

            max_area = max(max_area, cur_height * cur_width)
        return max_area
コード例 #6
0
    def dailyTemperatures(self, T: List[int]) -> List[int]:
        """
        核心:
            1.单调栈
            2.单调栈记录特殊数组 [val, index]
        :param T:
        :return:
        """
        t_len = len(T)
        res_lis = [0] * t_len
        stack = Stack()  # stack 记录特殊数组 [值, 位置index]

        for i in range(t_len - 1, -1, -1):
            # 1.维护单调栈
            while not stack.is_empty() and T[i] >= stack.peek()[0]:
                stack.pop()

            # 2.利用单调栈
            res_lis[i] = 0 if stack.peek() is None else stack.peek()[1] - i

            # 3.元素 push 进入单调栈
            stack.push([T[i], i])
        return res_lis
コード例 #7
0
class MinStack:
    def __init__(self):
        self._stack = Stack()
        self._min_stack = Stack()  # 使用辅助栈,来记录当前最小值

    def push(self, x: int) -> None:
        self._stack.push(x)

        # min_stack push 当前栈最小值
        if self._min_stack.peek() is None:
            self._min_stack.push(x)
        else:
            self._min_stack.push(min(x, self._min_stack.peek()))

    def pop(self) -> None:
        self._stack.pop()
        self._min_stack.pop()

    def top(self) -> int:
        return self._stack.peek()

    def getMin(self) -> int:
        return self._min_stack.peek()
コード例 #8
0
    @staticmethod
    def move_bottom_to_top(s: Stack):
        s.items.append(s.items.pop(0))

    def reverseStack(self, s: Stack) -> Stack:
        # 递归边界
        if s.is_empty() or s.size == 1:
            return s

        # 将底部元素移到顶部
        self.move_bottom_to_top(s)
        # 该栈 pop 出一个元素并记录在 top 中,形成子栈,并递归调用翻转方法
        top = s.pop()
        s = self.reverseStack(s)

        # 翻转后的子栈,push 原来的 top 元素
        s.push(top)
        return s


if __name__ == "__main__":
    solution = Solution()
    stack = Stack()
    for i in range(5):
        stack.push(i)

    stack = solution.reverseStack(stack)
    for i in range(10):
        print(stack.pop())
    pass