720220119_datawhale33期_leetcode刷题_7单调栈

七 单调栈

请添加图片描述Images Source: https://realpython.com/

来源

Datewhale33期__LeetCode 刷题 :

1 基础知识

单调栈(Monotone Stack):一种特殊的栈。在栈的「先进后出」规则基础上,要求「从 栈顶 到 栈底 的元素是单调递增(或者单调递减)」。其中满足从栈顶到栈底的元素是单调递增的栈,叫做「单调递增栈」。满足从栈顶到栈底的元素是单调递减的栈,叫做「单调递减栈」。


单调栈的性质:

1.单调栈里的元素具有单调性

2.元素加入栈前,会在栈顶端把破坏栈单调性的元素都删除 ---- 直到满足单调

3.使用单调栈可以找到元素向左遍历第一个比他小的元素,也可以找到元素向左遍历第一个比他大的元素。


单调栈可以在时间复杂度为O(n)的情况下,求解出某个元素左边或者右边第一个比它大或者小的元素。所以单调栈一般用于解决一下几种问题:

  • 寻找左侧第一个比当前元素大的元素
  • 寻找左侧第一个比当前元素小的元素
  • 寻找右侧第一个比当前元素大的元素
  • 寻找右侧第一个比当前元素小的元素

2 相关题目

2.1 503 . 下一个更大元素 II

  • 思路: 环 >>>构建双倍长度的数组 >>> 利用单调递减栈记下索引
class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        nums_2 = nums + nums
        stack, ans = [], [-1 for _ in range(len(nums_2))]
        for i in range(len(nums_2)):
            while stack and nums_2[stack[-1]] < nums_2[i]:
                ans[stack[-1]]  = nums_2[i]
                stack.pop()
            stack.append(i)
        return ans[:len(nums)] 

2.2 316 . 去除重复字母

  • 思路: 哈希去重 >>> 维护单调递增单调栈 >>> 并且单调栈内容
class Solution:
    def removeDuplicateLetters(self, s: str) -> str:
        stack, d = [], {}
        for ch in s:
            if ch not in d:
                d[ch] = 1
            else:
                d[ch] += 1
        
        for ch in s:
            if ch not in stack:
                while stack and stack[-1] > ch and d[stack[-1]] > 0:
                    stack.pop()
                stack.append(ch)
            d[ch] -= 1
        return "".join(stack) 

2.3 42 . 接雨水

  • 思路 : 雨水两侧为空则填充, 碰到矩形则停止 >>>>> 递减单调栈

在这里插入图片描述

易知
水高度: min(height[left],height[i])−height[top]
水的宽度: i-stack[left] - 1

  • 思路-----------单调栈
class Solution:
    def trap(self, height: List[int]) -> int:
        stack, ans, size = [], 0, len(height)
        for i in range(size):
            while stack and height[i] > height[stack[-1]]:
                temp = height[stack[-1]]
                stack.pop()
                if not stack: break   #如栈空停止while
                ans += (min(height[i], height[stack[-1]]) - temp)*(i - stack[-1] - 1)
            stack.append(i)
        return ans
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值