[Leetcode] [单调栈] Python 刷题总结

碰到很多次单调栈的题不会了,拿出来总结一下,题都比较类似。
基本上是求比当前元素更大(小)的上一个、下一个元素。

下一个最大值系列:

496. Next Greater Element I(Easy)

    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
        d, stack = {}, []
        for i in range(len(nums2)):
            while stack and nums2[i] > stack[-1]:
                d[stack.pop()] = nums2[i]
            stack.append(nums2[i])
        return [d.get(n,-1) for n in nums1]

503. Next Greater Element II

# 把数组长度扩大到两倍,每次存入其位置即可。
class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        stack, d = [], {}
        n = len(nums)
        nums = nums + nums
        for i in range(len(nums)):
            while stack and nums[stack[-1]] < nums[i]:
                d[stack.pop()] = nums[i]
            stack.append(i)
        return [d.get(i, -1) for i in range(n)]

84. Largest Rectangle in Histogram(Hard)

    def largestRectangleArea(self, heights: List[int]) -> int:
        if not heights:
            return 0
        stack = [-1]  #栈存储的是位置,加入了0在末尾(-1的位置),方便最后把stack清空
        res = 0
        heights.append(0)
        for i in range(len(heights)):
            while stack and heights[i] <= heights[stack[-1]]: #存储递增序列
                h = heights[stack.pop()]
                prev_pos = stack[-1] if stack else -1  #取stack前一个位置
                res = max(res, (i-prev_pos-1) * h)   
            stack.append(i)   
        return res

907. Sum of Subarray Minimums

该题也是hulu19年笔试的第二道题
试想对于每一位数,找出数组最小值。最小值将数组一分为二。leftLen 是左边长度,rightLen是右边长度。所有包含该最小值的子数组的最小值即该值。个数为 (leftLen + 1)*(rightLen+1)。再分别计算左数组和右数组的子数组最小值之和。使用单调栈的数据结构也就显而易见了。

class Solution:
    # Stack
    def sumSubarrayMins(self, A: List[int]) -> int:
        if not A:
            return 0
        stack = []
        A = [0] + A
        A.append(0)
        Mod = 10 ** 9 + 7
        Sum = 0
        for i in range(len(A)):
            while stack and A[i] < A[stack[-1]]:
                mid = stack.pop()
                Sum += (mid-stack[-1]) * (i-mid) * A[mid] % Mod #(mid-start)*(end-mid)*A[mid]
            stack.append(i)
        return Sum % Mod

参考文献:
https://blog.csdn.net/qq_17550379/article/details/86519771

你可能感兴趣的:([Leetcode] [单调栈] Python 刷题总结)