单调栈学习与应用

单调栈应用介绍 栈(Stack)是另一种操作受限的线性表,只允许元素从栈的顶端进顶端出,具有后进先出(LIFO)的特性。但单调栈(Monotonic Stack)是一种特殊的栈,在满足栈特性的基础上,栈内元素从栈底到栈顶具有单调性。如果栈底到栈顶元素是单调递减,则称为单调递减栈;如果栈底到栈顶元素是单调递增,则称为单调递增栈。新元素加入栈顶时,需要进行单调性维护,弹出不满足单调性的栈顶元素当前解计算是在出栈的时候进行的。 阅读详情

单调栈学习与应用

栈的应用,单调栈就是保持栈内元素有序,需要我们自己维持顺序,从栈顶到栈底是从小到大和从大到小两种情况。

  • 若要找第一个小于的,则应该从大到小
  • 若要找第一个大于的,应该从小到大

【LeetCode】84. 柱状图中最大的矩形

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:

输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10

示例 2:

输入: heights = [2,4]
输出: 4

提示:

  • 1 <= heights.length <=105
  • 0 <= heights[i] <= 104

思路

对于每一个柱子,想要合并成更大的矩形,只有两侧的柱子的高度大于等于当前这个柱子才能够合并,对于暴力解法来说,只要找到每一个柱子左侧第一个小于它高度的柱子,右侧第一个小于它高度的柱子,就能求出每一个柱子的合并最大矩形,遍历每个柱子就可以得到最大值!

若使用单调栈:

  1. 当前柱子高度大于栈顶柱子的高度

    • 入栈
  2. 当前柱子高度等于栈顶柱子的高度

    ​ 1和2代表两种不同的思路:

    1. 弹出栈顶柱子,入栈当前柱子(代表对于相同高度的柱子不重复计算)
    2. 直接入栈(代表遍历每一个柱子的合并面积,取最大值)
  3. 当前柱子高度小于栈顶柱子的高度 矩形面积为 height * width

    1. 弹出栈顶柱子,以当前栈顶柱子高度进行合并 下标为left
    2. 不弹出新栈顶柱子,以新栈顶柱子为左侧第一个小于要合并的高度的柱子 下标为cur
    3. 以当前遍历的柱子为右侧第一个小于要合并的高度的柱子 下标为right
    4. width = right - left - 1
    5. 计算面积并选取面积最大值,如果当前遍历柱子高度仍小于新栈顶柱子高度,则继续重复1-5步骤
    6. 将当前遍历的柱子入栈

因为单调栈是有序的,当找到第一个小于栈顶的,则栈顶的下一个柱子一定是小于栈顶的(如果是相等的也看作是小于的),所以就可以用栈顶柱子,栈顶下一个柱子,当前遍历柱子计算出合并面积!

例子

heights = [2,1,5,6,2,3]
添加哨兵后heights = [0,2,1,5,6,2,3,0]
heights[0]=0,入栈s=[0]
heights[1]=2,入栈s=[0,1]
heights[2]=1 < 2,pop出栈顶元素1,s=[0],可以确定heights[1]=2所能勾勒出的最大矩形面积,左边界为新栈顶元素0,右边界就是当前下标i=2,宽为2-0-1=1,高度为heights[1]=2,ans=max(0,2)=2。1>heights[0]=0,所以不继续pop,入栈s=[0,2]
heights[3]=5,入栈s=[0,2,3]
heights[4]=6,入栈s=[0,2,3,4] 
heights[5]=2 < heights[4]=6,pop出栈顶元素4,s=[0,2,3],可以确定heights[4]=6所能勾勒出的最大矩形面积,左边界为新栈顶元素3,右边界就是当前下标i=5,宽为5-3-1=1,高度为heights[4]=6,ans=max(2,6)=6
             < heights[3]=5,pop出栈顶元素3,s=[0,2],可以确定heights[3]=5所能勾勒出的最大矩形面积,左边界为新栈顶元素2,右边界就是当前下标i=5,宽为5-2-1=2,高度为heights[3]=5,ans=max(6,10)=10。2>heights[2]=1,所以不继续pop,入栈s=[0,2,5]
heights[6]=3,入栈s=[0,2,5,6]
heights[7]=0 < heights[6]=3,pop出栈顶元素6,s=[0,2,5],可以确定heights[6]=3所能勾勒出的最大矩形面积,左边界为新栈顶元素5,右边界就是当前下标i=7,宽为7-5-1=1,高度为heights[6]=3,ans=max(10,3)=10
             < heights[5]=2,pop出栈顶元素5,s=[0,2],可以确定heights[5]=2所能勾勒出的最大矩形面积,左边界为新栈顶元素2,右边界就是当前下标i=7,宽为7-2-1=4,高度为heights[5]=2,ans=max(10,8)=10
             < heights[2]=1,pop出栈顶元素2,s=[0],可以确定heights[2]=1所能勾勒出的最大矩形面积,左边界为新栈顶元素0,右边界就是当前下标i=7,宽为7-0-1=6,高度为heights[2]=1,ans=max(10,6)=10。不继续pop,入栈s=[0,7]
遍历结束,ans=10

tips

若所有柱子全部都是单调递增的,则找不到左右侧第一个小于的,则无法计算合并面积,怎么办?

例如:5 5 6

在开头和末尾加一个高度为0的哨兵即可,这样保证了栈一定不为空,同时,能保证一定能计算所有柱子的合并面积!

前后加0后:0 5 5 6 0,保证每个柱子都找得到比它小的

代码

弹出栈顶柱子,入栈当前柱子(代表对于相同高度的柱子不重复计算)

class Solution {
    public int largestRectangleArea(int[] heights) {
        int[] newHeights = new int[heights.length + 2];
        for(int i = 0; i < heights.length; i++) {
            newHeights[i + 1] = heights[i];
        }
        heights = newHeights;
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        int res = 0;
        for(int i = 1; i < heights.length; i++) {
            if(heights[i] > heights[stack.peek()]) {
                stack.push(i);
            }else if(heights[i] == heights[stack.peek()]){
                stack.pop();
                stack.push(i);
            }else {
                while(heights[i] < heights[stack.peek()]) {
                    int cur = stack.pop();
                    int left = stack.peek();
                    int right = i;
                    int height = heights[cur];
                    int width = right -left - 1;
                    res = Math.max(res, height * width);
                }
                stack.push(i);
            }
        }
        return res;
    }
}

直接入栈(代表遍历每一个柱子的合并面积,取最大值)

class Solution {
    public int largestRectangleArea(int[] heights) {
        int[] newHeights = new int[heights.length + 2];
        for(int i = 0; i < heights.length; i++) {
            newHeights[i + 1] = heights[i];
        }
        heights = newHeights;
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        int res = 0;
        for(int i = 1; i < heights.length; i++) {
            if(heights[i] > heights[stack.peek()]) {
                stack.push(i);
            }else if(heights[i] == heights[stack.peek()]){
                stack.push(i);
            }else {
                while(heights[i] < heights[stack.peek()]) {
                    int cur = stack.pop();
                    int left = stack.peek();
                    int right = i;
                    int height = heights[cur];
                    int width = right -left - 1;
                    res = Math.max(res, height * width);
                }
                stack.push(i);
            }
        }
        return res;
    }
}

化简:

class Solution {
    public int largestRectangleArea(int[] heights) {
        int[] newHeights = new int[heights.length + 2];
        for(int i = 0; i < heights.length; i++) {
            newHeights[i + 1] = heights[i];
        }
        heights = newHeights;
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        int res = 0;
        for(int i = 1; i < heights.length; i++) {
            while(heights[i] < heights[stack.peek()]) {
                int cur = stack.pop();
                int left = stack.peek();
                int right = i;
                int height = heights[cur];
                int width = right -left - 1;
                res = Math.max(res, height * width);
            }
            stack.push(i);
        }
        return res;
    }
}

【LeetCode】42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

示例 1:

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

思路

使用单调栈,就是出现有坑的时候就能存储水,怎样判断出现坑?当出现第一个大于栈顶柱子高度的柱子时,出现坑。那么单调栈的顺序从栈顶到栈底就应该是从小到大。单调栈的方法是以行计算雨水量。

在这里插入图片描述

  1. 当前柱子高度小于栈顶柱子的高度

    • 入栈
  2. 当前柱子高度等于栈顶柱子的高度

    ​ 1和2代表两种不同的思路:

    1. 直接入栈(代表对于相同高度的柱子分别成坑计算,比如有两个相同高度的柱子相邻和下图的情况)

      在这里插入图片描述

      1.当①和②中间的高度为0的柱子被弹出后②作为栈顶,①为左侧大于②的柱子(也就是栈顶下一个柱子),②右侧的柱子为右侧大于②的柱子(也就是当前遍历的柱子),形成了坑,其接的雨水为1个宽度

      2.当②弹出后,①作为栈顶,①左侧柱子作为左侧大于①的柱子(也就是栈顶下一个柱子),②右侧的柱子为右侧大于①的柱子(也就是当前遍历的柱子),形成了坑,其接的雨水是两个宽度

    2. 弹出栈顶柱子,入栈当前柱子(直接计算有相同高度柱子的承接雨水最大值,相当于一步到位)

  3. 当前柱子高度大于栈顶柱子的高度 雨水面积为 h * width

    1. 弹出栈顶柱子,以当前栈顶柱子高度进行合并 下标为left
    2. 不弹出新栈顶柱子,以新栈顶柱子为左侧第一个小于要合并的高度的柱子 下标为cur
    3. 以当前遍历的柱子为右侧第一个小于要合并的高度的柱子 下标为right
    4. width = right - left - 1
    5. h = Math.min(height[stack.peek()], height[right]) - height[cur];
    6. 计算雨水并累加,如果当前遍历柱子高度仍大于新栈顶柱子高度,则继续重复1-5步骤
    7. 将当前遍历的柱子入栈

代码

直接入栈

class Solution {
    public int trap(int[] height) {
        int len = height.length;
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        int sum = 0;
        for(int i = 1; i < len; i++) {
            if(height[i] < height[stack.peek()]) {
                stack.push(i);
            }else if(height[i] == height[stack.peek()]) {
                stack.push(i);
            }else {
                while(!stack.isEmpty() && height[i] > height[stack.peek()]) {
                    int cur = stack.pop();
                    if(!stack.isEmpty()) {
                        int right = i;
                        int left = stack.peek();
                        int h = Math.min(height[left], height[right]) - height[cur];
                        int width = right - left - 1;
                        sum += h * width;
                    }
                }
                stack.push(i);
            }
        }
        return sum;
    }
}

简化:

class Solution {
    public int trap(int[] height) {
        int len = height.length;
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        int sum = 0;
        for(int i = 1; i < len; i++) {
            while(!stack.isEmpty() && height[i] > height[stack.peek()]) {
                int cur = stack.pop();
                if(!stack.isEmpty()) {
                    int right = i;
                    int left = stack.peek();
                    int h = Math.min(height[left], height[right]) - height[cur];
                    int width = right - left - 1;
                    sum += h * width;
                }
            }
            stack.push(i);
        }
        return sum;
    }
}

弹出栈顶柱子,入栈当前柱子

class Solution {
    public int trap(int[] height) {
        int len = height.length;
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        int sum = 0;
        for(int i = 1; i < len; i++) {
            if(height[i] < height[stack.peek()]) {
                stack.push(i);
            }else if(height[i] == height[stack.peek()]) {
                stack.pop();
                stack.push(i);
            }else {
                while(!stack.isEmpty() && height[i] > height[stack.peek()]) {
                    int cur = stack.pop();
                    if(!stack.isEmpty()) {
                        int right = i;
                        int left = stack.peek();
                        int h = Math.min(height[left], height[right]) - height[cur];
                        int width = right - left - 1;
                        sum += h * width;
                    }
                }
                stack.push(i);
            }
        }
        return sum;
    }
}
数据结构与算法中单调栈的常见误区 本文旨在帮助读者深入理解单调栈的概念和工作原理,识别并避免在使用单调栈时的常见误区。我们将从基础概念出发,逐步深入到实际应用和性能分析。介绍单调栈的核心概念分析单调栈的常见误区展示单调栈的实际应用案例提供正确使用单调栈的实践建议单调栈(Monotonic Stack): 一种特殊的栈结构,其中的元素保持单调递增或单调递减的顺序。栈(Stack): 一种遵循"后进先出"(LIFO)原则的数据结构。核心概念回顾单调栈是一种保持元素单调性的特殊栈结构它有递增和递减两种形式,适用于不同问题。 阅读详情

相关推荐

【算法学习之路】9.单调栈

!单调栈的元素是严格单调递增和递减也就是说从栈底到栈顶元素的值逐渐增大或减小,多用于求解元素的左右大小边界问题:如:找左边第一个比自身大的数找左边第一个比自身小的数找右边第一个比自身大的数找右边第一个比自身小的数。

2401_86663413的博客 815

单调栈的应用

单调栈,顾名思义,就是存放的元素是单调的栈。 单调栈主要是用来计算某个数左边/右边第一个比它小/大的数,基本上所有单调栈的题都是用到单调栈的这个功能。 下面以计算某个数左边第一个比它小的数为例,如果是暴力,对于一个数而言,复杂度是可以接受的,但是倘若要对一个数组所有的数字都计算左边第一个比他小的数呢? 于是要利用单调栈。观察一串序列 3 9 7 4 5 我们要计算每个数左边第一个比他小的数(没有则输出-1) ,显然,第一个数的答案是-1,将3压入单调栈。 计算数字9 时,我们发现单调栈的

qq_50748356的博客 1194

训练日记-12

这两天主要学习了一下单调队列,研究了一下课件中单调队列的例题,并把训练二中单调队列的题目都给刷了。单调队列的算法并没有什么难度,难点就在于如何单调队列与相应的题目结合起来,不同的题目需要求的解也是不同的,其难点就相当于如何将题目所求的解如何单调队列表示出来。        其次从网上看了一下单调栈的基本知识以及相关算法,单调栈具有如下性质:        1.单调栈里的元素具有单调性。  

G_Meteor的博客 308

单调栈完全解析

形如子矩阵这样的问题,我们要解决此类问题有一个最大的约束,那就是保证这个图形是一个矩阵。单调栈可以做到这一点。而对于一个二维的空间来说,我们可以把一个二维空间压缩成很多个一维空间,每一个一维空间都可以使用单调栈求解。而二维空间的答案可以通过一维空间来求解。在这里可能需要一些概率论的知识,把一个大问题的求得得以分解成很多小的,可以分解成一维的问题来解决。

qq_61039408的博客 1313

机器学习——径向基函数(RBF)神经网络

目录 一、什么是基函数 二、什么是径向基函数 三、为什么RBF神经网络使用一个径向基函数作为隐含层的激活函数 四、参数训练 五、RBF网络vs BP网络和 SVM 一、什么是基函数 著名的傅里叶变换是指:n个有参(权值)的正、余弦三角函数基的和式可以等价的表示任意一个周期函数,这里的“基”和我们数学中说的坐标基或向量基含义相同,即坐标空间中任意一个向量都可以用基向量的线性和表示出来。 因此,我们引入函数空间的概念,函数空间中的每个连续函数可以表示为基函数的线性组合,就像向量空间中的每..

CHWB2580的博客 6271

从零到一:Firefly-RK3399上的Ubuntu镜像构建与GPU加速实战

本文详细介绍了在Firefly-RK3399开发板上从零构建深度优化的Ubuntu系统镜像的全过程,包括交叉编译环境配置、内核定制、GPU加速环境部署(Mesa Panfrost驱动、OpenCL/Vulkan支持)以及深度学习推理优化(TFLite + LinuxNN)。通过实战案例展示了如何充分发挥Mali-T860 GPU的硬件潜力,提升边缘AI应用的性能和能效。

pz8901234的博客 1019

栈的学习心得与单调栈相关应用

对于单调递减栈,从栈底到栈顶元素是从大到小排列。可以看到,在while循环中,我们通过s.size()来确保栈的层数不为0,同时判断将要进行查找是否小于栈顶元素,以判断是否需要移除栈顶元素,直到栈的层数为0或栈顶元素大于改目标元素。而使用单调栈进行查找时,我们实际上从头到尾的查找使用的是同一个不断更新的单调栈,即已经被查找过的元素不再需要被进行比较,这种的方法的时间复杂度是O(n)。在运行的过程中,只有比栈顶元素小的元素才能直接进栈,否则需要先将栈中比当前元素小的元素出栈,再将当前元素入栈。

qq_45366213的博客 1052

易智联LM401模块学习(一)——初识Lora

Lora

weixin_46046597的博客 1053

图解单调栈:零基础也能懂的工作原理

建议刚开始可以重点玩转前两个模块,把单调栈的"后进先出"和"单调性维护"两个特性吃透。上部署这个项目时,发现他们的托管服务特别适合这种需要持续交互的应用。不需要配置任何服务器环境,点几下就能上线运行,还能自动生成可分享的演示链接。对于想学算法又怕环境配置的同学,这种开箱即用的体验真的很友好。第一次听到"单调栈"这个词时,我完全摸不着头脑。后来发现它就像超市排队结账时的VIP通道——只允许比当前顾客消费金额更高的人插队。今天想和大家分享一个特别适合算法新手的可视化学习工具——单调栈交互教程。

SnowflakeJaguar14的博客 413

【COMSOL超材料和超表面仿真设计】

超材料和超表面的设计通常需要自定义材料属性。在COMSOL中,可以通过定义介电常数和磁导率的张量来模拟超材料的特性。对于超表面,通常需要定义表面阻抗或等效电路模型。

weixin_51101456的博客 1659

【电脑技巧】CPU正常运行时间过长,怎么解决?

目录 问题描述 解决方案 1、问题描述 不少同志都遇到过这样的问题:按【Ctrl + alt + delete】打开任务管理器,切到“性能”选项卡下,发现自己电脑的CPU正常运行时间竟然为好几十天!很多人担心这会不会影响电脑的寿命?于是很想知道这是怎么回事,以及如何解决这个问题。 我在此解答一下,这是由于你的电脑开启了“快速启动”这一选项的缘故,只要把这一选项关闭,问题就解决了。 2、解决方案 怎样关闭“快速启动”呢?按照如下的步骤来即可。 顺便声明一下,笔者的电脑配置: 使用电脑:联想Yoga 14

橄榄树下的孩子 3万+

java-NC157_单调栈

java-NC157 单调栈。

d3y1`5 81_09 362

4D毫米波雷达:高度信息与微多普勒效应

4D毫米波雷达:高度信息与微多普勒效应​ ,人工智能,计算机视觉,大模型,AI,本文深入解析4D毫米波雷达的高度信息获取与微多普勒效应。4D毫米波雷达通过MIMO技术、垂直天线布局及相位差计算等获取高度信息,相较传统雷达更精准。微多普勒效应由目标微运动引发,可用于目标识别、分类和运动监测。文中结合自动驾驶、安防监控案例,分析技术挑战与未来趋势,如信号干扰、数据处理复杂,未来将向高精度、与其他传感器融合发展,展现出在多领域的巨大应用潜力。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 9万+

单调栈

一、定义 从栈底元素到栈顶元素呈单调递增或单调递减,栈内序列满足单调性的栈; 二、原理 (1)当新元素在单调性上优于栈顶时(单增栈新元素比栈顶大,单减栈新元素比栈顶小),压栈,栈深+1; (2)当新元素在单调性与栈顶相同(新元素于栈顶相同)或劣于栈顶时(单增栈新元素比栈顶小,单减栈新元素比栈顶大),弹栈,栈深-1; 三、leetcode 【接雨水】 使用单调栈,【单调栈入门】 单调递减栈 1. 2.1 理解题目,参考图解,注意题目的性质,当后面的柱子高度比前面的低时,是无法接雨水的 2. 2.2 当

cwl110120的博客 260

【网络安全】SSRF漏洞讲解

SSRF漏洞讲解一、初识SSRF漏洞1.定义2.产生原理3.会导致的危害4.常见产生SSRF的地方5.常见缺失函数二、SSRF漏洞利用1.函数(1) file_get_contents(2)fsockopen()(3) curl_exec()2.协议(1)file协议(2)http协议(3)dict协议(4)gopher协议三、绕过1.绕过方式(1)检查IP是否为内网IP(2)Host获取与DNS绕过(3)通过各种协议(4)利用URL解析器滥用问题四、修复修复方案五、小结 一、初识SSRF漏洞 1.定义

你在看屏幕的同时,屏幕也在注视着你 3180

configure: error: no acceptable C compiler found in $PATH解决方案

本文主要介绍了configure: error: no acceptable C compiler found in $PATH解决方案,希望能对使用Linux的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 4万+

907. 子数组的最小值之和(单调栈)

心情:每次写说明心态肯定是崩的、、、、 关于单调栈的解释,这个博主讲的很好单调栈 我这里只想记录一下,能用到单调栈的情况: 比如这题,还有求最小图形的,这些题都有个特点,就是连续,且求最值。 其实这种题目最原始的想法,就是找以当前点为中心满足条件的一个范围,意思就是在当前节点的基础上,往左和往右循环,找出能延展的最大范围,但这样做往往会超时,于是就有了单调栈。 单调栈是一种结构,其实这个结构很好理...

cirol1997的博客 244

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

[单调栈专题]

https://vjudge.net/contest/296911#overview A - Subsequence There is a sequence of integers. Your task is to find the longest subsequence that satisfies the following condition: the differe...

aiyuneng5167的博客 305

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

离散化、KMP和单调栈队列洛谷习题

离散化算法模板:(来自 AcWing) vector alls; // 存储所有待离散化的值 sort(alls.begin(), alls.end()); // 将所有值排序 alls.erase(unique(alls.begin(), alls.end()), alls.end()); // 去掉重复元素 // 二分求出x对应的离散化的值 int find(int x) // 找到第一个大于等于x的位置 { int l = 0, r = alls.size() - 1; while (l < r

Quorra_chord的博客 876

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

图解单调栈:五分钟搞懂这个神奇数据结构

想象一下奶茶店排队的情景:新来的顾客会看前面人的身高,如果前面有比自己矮的,这些矮个子就会被新顾客"挤出去",直到遇到更高的人才会停下。这就是单调栈的核心思想——维护一个有序的序列(这里是单调递减的),不符合条件的元素会被移除。最近在学习算法时接触到了单调栈这个概念,一开始觉得有点抽象,但通过一些生活化的比喻和可视化演示后,发现其实很容易理解。今天就来分享一下我的学习心得,希望能帮助同样刚入门的朋友快速掌握这个数据结构。通过这样循序渐进的学习方式,相信大家都能很快掌握单调栈这个看似复杂实则简单的数据结构。

AmberLeopard26的博客 349

单调栈leetcode.907

int MOD = (int)1e9+7; public int sumSubarrayMins(int[] arr) { int n = arr.length, ans = 0; Deque d = new ArrayDeque();//单调栈存储索引 for (int r = 0; r

路的博客 377

单调栈+单调队列+尺取+滑动窗口

尺取 单调栈+单调队列

江上酒 211

算法学习单调栈

单调栈是指栈内元素保持单调递增或单调递减顺序的一种栈结构。这种特性使得单调栈在解决某些特定类型的问题时表现出色,如寻找下一个更大或更小的元素、区间查询等。

一个做过前端开发的产品经理,经历过睿智产品的折磨导致脱发之后,励志要翻身"农奴"把歌唱,一边打入敌人内部一边持续提升自己,为我们广大开发同胞谋福祉,坚决抵制睿智产品折磨我们码农兄弟! 960

python学习记录2

本文涵盖了Python面试中的技术问题和HR问题,主要内容包括: 技术问题:详细解析了单调栈和单调队列的工作原理、应用场景及时间复杂度,如解决滑动窗口最大值、柱状图最大矩形等问题。 循环结构:介绍了Python的for和while循环语法及适用场景,并分析了循环控制语句(break、continue、else)的作用与示例。 代码题:包含10道选择题,涉及循环逻辑、斐波那契数列、条件控制等,如输出嵌套循环结果、修正求和代码错误等,HR面试相关问题。

2503_90172382的博客 869
上一篇: 【LeetCode】309. 最佳买卖股票时机含冷冻期 动态规划 状态转移分析
下一篇: 【LeetCode】48. 旋转图像
Sancean
博客等级 码龄6年 2472粉丝 149原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值