面试刷题必会:单调栈python模板套路(附用法例题详解)

单调栈问题:

要知道单调栈的适用于解决什么样的问题,首先需要知道单调栈的作用。单调栈分为单调递增栈和单调递减栈,通过使用单调栈我们可以访问到下一个比他大(小)的元素(或者说可以)。

也就是说在队列或数组中,我们需要通过比较前后元素的大小关系来解决问题时我们通常使用单调栈。下面我们通过简单介绍单调减栈和单调增栈问题来进一步说明使用单调栈处理问题的过程。

什么时候使用单调栈?
通常是一维数组,要寻找任一元素右边(左边)第一个比自己大(小)的元素,且要求 O(n) 的时间复杂度

单调栈原理:

单调递增栈:从 栈底 到 栈顶 递增,栈顶大
单调递减栈:从 栈底 到 栈顶 递减,栈顶小

python模板套路:

1): 当前项向右找第一个比自己大的位置 —— 从右向左维护一个单调递减栈。

def nextGreaterElement_01(nums: list):
    length = len(nums)
    res, stack = [-1] * length, []

    for i in range(length - 1, -1, -1):
        while stack and stack[-1] <= nums[i]:
            stack.pop()
        if stack:
            res[i] = stack[-1]
        stack.append(nums[i])

    return res

或者 当前项向右找第一个比自己大的位置 —— 从左向右维护一个单调递减栈。

def nextGreaterElement_011(nums: list):
    length = len(nums)
    res, stack = [-1] * length, []

    for i in range(length):
        while stack and nums[stack[-1]] < nums[i]:
            idx = stack.pop()
            res[idx] = nums[i]
        stack.append(i)

    return res

2):当前项向右找第一个比自己小的位置 —— 从右向左维护一个单调递增栈

def nextGreaterElement_02(nums: list):
    length = len(nums)
    res, stack = [-1] * length, []

    for i in range(length - 1, -1, -1):
        while stack and stack[-1] >= nums[i]:
            stack.pop()
        if stack:
            res[i] = stack[-1]
        stack.append(nums[i])

    return res

3): 当前项向左找第一个比自己大的位置 —— 从左向右维护一个单调递减栈

def nextGreaterElement_03(nums: list):
    length = len(nums)
    res, stack = [-1] * length, []

    for i in range(length):
        while stack and stack[-1] <= nums[i]:
            stack.pop()
        if stack:
            res[i] = stack[-1]
        stack.append(nums[i])

    return res

4): 当前项向左找第一个比自己小的位置 —— 从左向右维护一个单调递增栈

def nextGreaterElement_04(nums: list):
    length = len(nums)
    res, stack = [-1] * length, []

    for i in range(length):
        while stack and stack[-1] >= nums[i]:
            stack.pop()
        if stack:
            res[i] = stack[-1]
        stack.append(nums[i])

    return res

参考来源:https://leetcode-cn.com/problems/next-greater-element-i/solution/dan-diao-zhan-zong-jie-by-wu-xian-sen-2/

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
单调栈是一种常见的数据结构,在解决一些特定问题时非常有用。它可以用来求解一些范围内的最大值、最小值、最长连续递增子序列等问题。下面是一个简单的 Python 实现: ``` class MonotonicStack: def __init__(self): self.stack = [] def push(self, val): while self.stack and self.stack[-1] < val: self.stack.pop() self.stack.append(val) def pop(self): self.stack.pop() def top(self): return self.stack[-1] def is_empty(self): return len(self.stack) == 0 ``` 这个单调栈实现了四个基本操作: - push(val):将元素 val 压入中。在压入之前,如果顶元素比 val 小,则弹出顶元素,直到顶元素比 val 大或为空,然后将 val 压入中。 - pop():弹出顶元素。 - top():返回顶元素。 - is_empty():判断是否为空。 使用单调栈的时候,需要根据具体问题来实现 push 操作。下面是一个例子,求解一个数组中每个元素右边第一个比它大的数: ``` def next_larger(nums): n = len(nums) res = [-1] * n stack = MonotonicStack() for i in range(n): while not stack.is_empty() and nums[stack.top()] < nums[i]: res[stack.top()] = nums[i] stack.pop() stack.push(i) return res ``` 在这个例子中,我们维护了一个单调递减的,每次遇到一个比顶元素大的数,就将顶元素弹出,并将顶元素的答案设为当前数。这样,最后中剩下的元素都没有右边比它们大的数,它们的答案就是 -1。时间复杂度为 O(n)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值