单调栈

作者: madao756 | 来源:发表于2020-03-09 00:17 被阅读0次

    由于有四种情况的单调栈,为了不容易出错,我决定全部转换成「求左边第一个比自己小的」单调栈

    0X00 模板

    求左边第一个比自己小的 模板

    def make(a):
        n = len(a)
        ans = [float("inf")] * n
        stack = []
        for i, v in enumerate(a):
            while stack and stack[-1] >= v: stack.pop()
            if stack: ans[i] = stack[-1]
            stack.append(v)
        return ans
    
    • 如果求左边第一个比自己大的,就把原数组取负
    • 如果求右边第一个比自己小的,就把原数组取反,最后一定要思考是不是要反过来
    • 如果求右边第一个比自己大的,就把原数组取反,再全部取负数,最后也一定要思考是不是要反过来

    0X01 引申

    求左边比自己大的里面最小的

    我们把原数组的下标按照值按降序排序,然后左边第一个下标比自己小的就是「左边比自己大的里面最小的」

    975. 奇偶跳

    class Solution:
        def oddEvenJumps(self, A: List[int]) -> int:
            def make(a):
                stack, res = [], [None] * n
                for _, v in enumerate(a):
                    while stack and stack[-1] > v: stack.pop()
                    if stack: res[v] = stack[-1]
                    stack.append(v)
                return res
            
            n, A = len(A), A[::-1]
            B = sorted(range(n), key=lambda i: -A[i])
            oddprev = make(B)
            B = sorted(range(n), key=lambda i: A[i])
            evenprev = make(B)
            odd, even = [False] * n, [False] * n
            odd[0] = even[0] = True
            for i in range(1, n):
                if oddprev[i] != None:
                    odd[i] = even[oddprev[i]]
                if evenprev[i] != None:
                    even[i] = odd[evenprev[i]]
    
            return sum(odd)
    

    求左边比自己小的最大的

    把原数组的下标按升序排序,然后左边第一个下标比自己小的就是「左边比自己小的最大的」

    0X02 相关题目

    注意判断尽量使用 != None

    相关文章

      网友评论

          本文标题:单调栈

          本文链接:https://www.haomeiwen.com/subject/dgasdhtx.html