首页 > 其他分享 >08-单调栈

08-单调栈

时间:2023-11-09 09:12:42浏览次数:30  
标签:peek 示例 int 08 pos heights temperatures 单调

8. 单调栈

有个数组arr, 找到arr[i]左面比他小的第一个数, 和右面比他小的第一个数,要求O(N)的时间复杂度.

思路:栈底下栈顶从小到大,栈中存放位置信息,入栈或者出栈的时候可能需要记录信息。

8.1 每日温度

https://leetcode.cn/problems/daily-temperatures/

1. 题目

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

示例 2:
输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]

示例 3:
输入: temperatures = [30,60,90]
输出: [1,1,0]

2. 思路

用一个栈来维护天气,当第i个天气比peek大的时候,出栈,并且记录当前的结果。直到栈为空或者第i个天气比peek小(while结束),入栈

3. 代码

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int length = temperatures.length;
        int[] ans = new int[length];
        Deque<Integer> sk = new LinkedList<Integer>();
        for (int i = 0; i < length; i++) {
            // 出栈条件:栈不为空,并且当前值比栈顶大
            while(!sk.isEmpty() && temperatures[i] > temperatures[sk.peek()]){
                // System.out.println(temperatures[i]);
                // 
                ans[sk.peek()] = i - sk.peek();
                sk.pop();
            }
            sk.push(i);
        }
        return ans;
    }
}

8.2 柱状图中最大矩阵

1. 题目

https://leetcode.cn/problems/largest-rectangle-in-histogram/

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

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

示例1:

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

示例2:

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

2. 思路

严格递增的栈来存储

找左右两个方向上第一个比自己小的值

入栈的时候确定第i位置的最左位置(就是peek,因为他比最左大,并且比左面大),出栈的时候,确定当前peek的最右位置(因为出栈,所以第i位置的数比peek大,并且在右面)。

最后剩下的数说明,他们在最右侧没有比他小的了,弹栈并且,最右侧的值为len

3. 代码

class Solution {
    public int largestRectangleArea(int[] heights) {
        int len = heights.length;
        // 左边界位置
        int[] leftPos = new int[len];
        int[] rightPos = new int[len];
        // 单调栈 碰到小的出栈 栈内:4 5 6 ;2
        Stack<Integer> pos = new Stack<>();
        // 标记位置,防止出现xx情况
        pos.push(-1);
        int maxArea = 0;
        for(int i = 0; i < len; i++){
            while(pos.peek() != -1 && heights[pos.peek()] >= heights[i]){
               int curPos = pos.peek();
               int area = heights[curPos]*(i-leftPos[curPos]-1);
               if(area>maxArea) maxArea = area;
               pos.pop();
            }

            leftPos[i] = pos.peek();
            pos.push(i);
        }

        // 栈内弹出 -- 右边界是自己
        while(pos.peek() != -1){
            int curPos = pos.peek();
            int area = heights[curPos]*(len - leftPos[curPos]-1);
            if(area>maxArea) maxArea = area;
            pos.pop();
        }
        
        return maxArea;

    }
}

8.3 矩阵中最大矩形

1. 题目

https://leetcode.cn/problems/PLYXKQ/

给定一个由 01 组成的矩阵 matrix ,找出只包含 1 的最大矩形,并返回其面积。

注意:此题 matrix 输入格式为一维 01 字符串数组。

示例1:

输入:matrix = ["10100","10111","11111","10010"]
输出:6
解释:最大矩形如上图所示。

示例2:

输入:matrix = []
输出:0

示例3:

输入:matrix = ["0"]
输出:0

示例4:

输入:matrix = ["1"]
输出:1

示例5:

输入:matrix = ["00"]
输出:0

2. 思路

先统计每一行,左侧相邻的1的个数。

比如某一行1 0 1 1 0 1 1左侧相邻1的个数分别为 1 0 1 2 0 1 2

之后

方法1 :遍历矩阵O(mn),以遍历的点为右下角,向上看用O(N)的复杂度找到当前的最大面积。 总计O(m^2n)。

方法2 : 一次只看某一列,利用单调栈来求这一列的“面积”。在生成之后,才进行面积计算O(mn) + O(mn) = O(m*n)。

而后同8.2一样,利用单调栈,从右往左而后从左往右两次遍历得到结果。

3. 代码

标签:peek,示例,int,08,pos,heights,temperatures,单调
From: https://www.cnblogs.com/ylw-blogs/p/17818906.html

相关文章

  • 20231108数数与dp题笔记
    数数与dpCF294CShaassandLights记被分成的\(m+1\)段每一段的长度为\(l_i\)答案为\[\frac{(n-m)!}{\prod\limits_{i=1}^{m+1}l_i!}\times\prod\limits_{i=1}^{m+1}2^{l_i-1}\]前面是不同段之间的顺序打乱,后面是每一段中前\(l_i-1\)个操作各有\(2\)个选择CF1753CW......
  • 2023-11-08:用go语言,字符串哈希原理和实现 比如p = 233, 也就是课上说的选择的质数进制
    2023-11-08:用go语言,字符串哈希原理和实现比如p=233,也就是课上说的选择的质数进制"31256..."01234hash[0]=3*p的0次方hash[1]=3*p的1次方+1*p的0次方hash[2]=3*p的2次方+1*p的1次方+2*p的0次方hash[3]=3*p的3次方+1*p的2次方+2*p......
  • 每日总结20231108
    代码时间(包括上课)6h代码量(行):100行博客数量(篇):1篇相关事项:1、今天是周三,上午上的是软件构造,讲的是交互和测试,具体的交互内容包括和测试的方式包括。2、今天下午参加了一个电气院的用电安全知识竞赛。3、今天晚上打算复习复习数学,毕竟马上要考研。......
  • 11.08县哗
    今天只能待到8点半......
  • 单调栈学习笔记
    今天模拟赛B没想出来,甚至没到单调栈那一步。到了可能也不会做。发现单调栈已经忘干净了,之前学过的悬线法也不太会,这里补一下单调栈。板子:HISTOGRA-LargestRectangleinaHistogram在我的这篇博客里有题解。总之我自己是看懂了的。单调栈求最大全1子矩阵问题P4147玉......
  • 231108校内赛
    T1最大公约数数据极水,啥都能过第一种方法,暴力剪枝,直接飞过,\(\mathcalO(N^2\logn)\)过\(30\)万不解释玛德有人在提交时不写输出直接爆零#include<bits/stdc++.h>#defineN300010usingnamespacestd;intn,k,ans,a[N];intgcd(inta,intb){ returnb==0?a:gcd(b,......
  • cf908(div2)题解(补题)
    纪念这次div2让我上绿名,但还是有点遗憾,差一点就可以过三题超神了比赛链接cf908div2A这题是个骗人题,整个比赛会停下来就是一个人赢够了回合数,那么在谁这停下来就是谁赢了整个比赛,不用管每回合赢得规则。#include<iostream>usingnamespacestd;#include<string>intmain(){......
  • 【2023.11.08】NOIP2023模拟试题-30
    前言数论迎我归,数学送我葬组合数学不容易,又有DP当T3刚爆零,T4又遭殃OI路上怅前望,且行且彷徨T1最大公约数T1应该想一想就会,接下来我们讨论是怎么减去他的复杂度的。题目的关键在于,如果根据给出的\(a\)推出\(\gcd\)的话,就会有\(9\times10^{10}\)条推导关系。而......
  • 2023_11_08_Idea常用的快捷键
    一、常用快捷键Ctrl+F12弹出当前文件结构层(类的方法属性等),可以在弹出的层上直接输入,进行筛选Ctrl+左键单击在打开的文件标题上,弹出该文件路径Ctrl+N根据输入的类名查找类文件Ctrl+D复制光标所在行或复制选择内容,并把复制内容插入光标位置下面Ctrl+P方法......
  • 2023-11-08 Android studio下载的模拟器存放路径以及如何修改存放路径 ==》默认路径:C:
    模拟器存放默认路径:C:\Users\Administrator\.android\avd如何修改:设置一个系统变量,如图,点击Help==》EditCustomProperties 然后再弹出的文本框里输入你要存放的路径,比如我存在D盘的adv文件夹里面ANDROID_AVD_HOME=D:\\adv 我的as版本:2022.3.1Patch3 写到最后:c盘......