当前位置: 首页 > article >正文

单调栈算法

文章目录

  • 题目概述
  • 题目详解
    • 739.每日温度
    • 1475.商品折扣后的最终价格
    • 84.柱状图中最大的矩形

题目概述

单调栈:栈,并且栈是有序的
单调栈的两种写法:
左 -> 右,或者右 -> 左 建议使用左到右的写法

及时去掉无用元素,保证栈中元素有序

从左到右的思路中,更新是在while循环中的,也就是说while 是满足题目条件,用于解放栈中的元素的

基础题目

739.每日温度
1475.商品折扣后的最终价格

矩形

84.柱状图中最大的矩形

题目详解

739.每日温度

在这里插入图片描述

思路分析:这个题目如果使用暴力,则时间复杂度为o(n^2),会超时,我们可以考虑使用单调栈
单调栈:使用栈进行存储,并且栈内的元素是单调的
为什么使用单调栈?:假设我们从左往右进行计算,则我们需要寻找当前的temperature[i]的后续的第一个大的温度,如果找不到的话,我们首先得存储起来这个数,然后向后面遍历,如果后续 遇到了比最后一个存储起来的元素大的数,我们就解决了这个数,直到没有满足,按照这个顺序存储的数组,是单调的,并且都是先进后出,所以我们使用单调栈

# 从左到右的写法
class Solution:
    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        # 先用暴力求解,但是会超时,是o(n^2)
        # 考虑使用单调栈,先进后出,并且栈是有序的
        ans = [0]*(len(temperatures))
        st = []
        for i,c in enumerate(temperatures):
            # 如果栈不为空并且当前的元素比栈顶的元素大
            while st and c > temperatures[st[-1]]:
                # 栈顶的元素找到了temperature[i],则弹出
                ans[st[-1]] = i - st[-1]
                st.pop()
            st.append(i)
        return ans

# 从右到左的写法,替换上面的for循环即可
        for i in range(len(temperatures)-1,-1,-1):
            tem = temperatures[i]
            while st and tem >= temperatures[st[-1]]:
                st.pop()
            if st:
                ans[i] = st[-1] - i
            st.append(i)

1475.商品折扣后的最终价格

在这里插入图片描述

这题也比价简单,只用套模版即可

# 从左到右思路
class Solution:
    def finalPrices(self, prices: List[int]) -> List[int]:
        # 使用单调栈进行求解,单调栈存储的是 没有找到满足情况的元素的下标
        ans = [i for i in prices]
        st = []
        for i,c in enumerate(prices):
            # while 是解放栈的,只要当前元素小于等于栈顶即可
            while st and c <= prices[st[-1]]:
                ans[st[-1]] -= c 
                st.pop()
            st.append(i)
        return ans

84.柱状图中最大的矩形

在这里插入图片描述

思路分析:这个题目与基础的单调栈不同,需要考虑栈中剩余的元素,以及矩形的宽度,从一开始的情况


from typing import List

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        n = len(heights)
        ans = [0]*(len(heights))  # 初始化 ans 为全零数组
        st = []
        
        for i in range(n):
            # 当前的数 heights[i] 小于栈顶就可以解放栈里面元素
            while st and heights[i] < heights[st[-1]]:
                top = st.pop()
                # 计算以 heights[top] 为高的矩形的面积
                width = i if not st else i - st[-1] - 1
                ans[top] = heights[top] * width
            st.append(i)
        
        # 处理栈中剩余的元素
        while st:
            top = st.pop()
            width = n if not st else n - st[-1] - 1
            ans[top] = heights[top] * width
        
        return max(ans)

http://www.kler.cn/a/525724.html

相关文章:

  • 我的2024年博客总结(在工作、博客和生活中找到自己的生活节奏)
  • 51单片机开发:串口通信
  • AboutDialog组件的功能和用法
  • Haproxy入门学习二
  • ORA-04031 错误
  • SpringBoot或SpringAI对接DeekSeek大模型
  • Vue 3 30天精进之旅:Day 09 - 组合式API
  • vscode和pycharm的区别
  • PYH与MAC的桥梁MII/MIIM
  • 代理模式 -- 学习笔记
  • 深入理解Java并发编程中的原子操作、volatile关键字与读写锁
  • 手写MVVM框架-环境搭建
  • C#方法(练习)
  • rsync安装与使用-linux015
  • 2025最新版MySQL安装使用指南
  • android 圆形弹窗摄像头开发踩坑——源码————未来之窗跨平台操作
  • VS2008 - debug版 - 由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题。
  • 你的连接不是专用连接
  • 信息学奥赛一本通 1606:【 例 1】任务安排 1 | 洛谷 P2365 任务安排
  • Web-3.0(Solidity)基础教程
  • 【PySide6拓展】QWindowCapture
  • AI在自动化测试中的伦理挑战
  • 【Unity3D】实现横版2D游戏——单向平台(简易版)
  • 31【api接口】
  • 构建具身智能体的时空宇宙!GRUtopia:畅想城市规模下通用机器人的生活图景
  • Effective Objective-C 2.0 读书笔记——关联对象