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

大厂高频算法考点--单调栈

什么是单调栈:

单调栈就是借助一个栈,在仅仅使用当前栈的条件下,时间复杂度是N(n),将每个节点最有离这他最近的大于或者是小于的数据返回,将已知数组的元素放到栈里。再自我实现的代码里面我们使用数组实现栈结构,将我们的运算时间再次优化。

二.代码实现单调栈:

这个测试链接是牛客网的测试,大家可以再学习之后就测试一下。

https://www.nowcoder.com/practice/2a2c00e7a88a498693568cef63a4b7bb

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {private static int n, m,r; //n 代表数组的长度      之后的值就是数组的值  r是为了节约栈的空间,使用数组private static int[] arr = new int[1000001];private static int[] stack = newint[1000001];//栈里面仿制的是数组的下标private static int[][] ans = new int[1000001][2];public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//不是读取一行StreamTokenizer in = new StreamTokenizer(br);PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));while (in.nextToken() != StreamTokenizer.TT_EOF) {n = (int)in.nval;for (int i = 0; i < n; i++) {in.nextToken();arr[i] = (int)in.nval;}compute();//开始编写核心逻辑for (int i = 0; i < n; i++) {out.println(ans[i][0] + " " + ans[i][1]);}}out.flush();out.close();br.close();}// arr[0...n-1]public static void compute() {r = 0;int cur;// 遍历阶段for (int i = 0; i < n; i++) {while(r>0&&arr[stack[r-1]]>=arr[i]){cur=stack[--r];ans[cur][1]=i;ans[cur][0]=r>0?stack[r-1]:-1;}stack[r++]=i;}// 清算阶段while (r > 0) {cur=stack[--r];ans[cur][1]=-1;ans[cur][0]=r>0?stack[r-1]:-1;}// 修正阶段// 左侧的答案不需要修正一定是正确的,只有右侧答案需要修正// 从右往左修正,n-1位置的右侧答案一定是-1,不需要修正for (int i = n - 2; i >= 0; i--) {if (ans[i][1] != -1 &&arr[ans[i][1]] == arr[i]) { ans[i][1] = ans[ans[i][1]][1];}}}
}

 三.单调栈类型题总结

3.1  天气状况

这是leetcode上面的一个题,测试连接如下:739. 每日温度 - 力扣(LeetCode)

给定一个整数数组 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]

 这是题目的描述,我们可以尝试就是使用单调栈解决。答案如下:

class Solution {public int[] dailyTemperatures(int[] temperatures) {//创建答案数组int[] answer =new int[temperatures.length];//创建一个数组,实现栈的功能,注意这个栈实现的功能是只有比他大的时候出战int[] stack =new int[temperatures.length];int r=0;for(int i=0;i<temperatures.length;i++){int cur=0;while(r>0&&temperatures[stack[r-1]]<temperatures[i]){cur=stack[--r];answer[cur]=i-cur;}stack[r++]=i;}return answer; }}

3.2:907. 子数组的最小值之和 - 力扣(LeetCode)

就是查找比它小的数在哪里,那他就是当前数组里面最小的值了  
​
主要就是这个值在哪里呢。【1 3 4 5 2 5 7 1 2 3】【0 1 2 3 4 5 6 7 8 9】总结公式  
​
主要的优化就是即使是相等的也不需要总结这个单调栈。因为他缺的值在后续中会补上
​
【1 3 4 5 6 5 7 1 2 3】
​
【0 1 2 3 4 5 6 7 8 9】  
class Solution {public static int MOD = 1000000007;
​public int sumSubarrayMins(int[] arr) {//创建栈,开始计算结果int[] stack =new int[arr.length];int r=0;int cur=0;int[][] ans=new int[arr.length][2];for(int i=0;i<arr.length;i++){while(r>0&&arr[stack[r-1]]>arr[i]){cur=stack[--r];ans[cur][1]=i;ans[cur][0]=r>0?stack[r-1]:-1;}stack[r++]=i;}while(r>0){cur=stack[--r];ans[cur][1]=arr.length;ans[cur][0]=r>0?stack[r-1]:-1;}long sum=0;for(int i=0;i<ans.length;i++){//加法的取模运算没什么特殊的sum=(sum+(long)((long)arr[i]*(long)(i-ans[i][0])*(long)(ans[i][1]-i)))%MOD;}return (int)sum;}
}

 方法二:

class Solution {public static int MOD = 1000000007;
​public int sumSubarrayMins(int[] arr) {//创建栈,开始计算结果int[] stack =new int[arr.length];int r=0;int cur=0;long sum=0;for(int i=0;i<arr.length;i++){while(r>0&&arr[stack[r-1]]>arr[i]){cur=stack[--r];int right =i;int left=r>0?stack[r-1]:-1;//加法的取模运算没什么特殊的sum=(sum+(long)((long)arr[cur]*(long)(cur-left)*(long)(right-cur)))%MOD;}stack[r++]=i;}while(r>0){cur=stack[--r];int right =arr.length;int left=r>0?stack[r-1]:-1;sum=(sum+((long)arr[cur]*(long)(cur-left)*(long)(right-cur)))%MOD;}return (int)sum;}
}
执行用时分布
6ms
击败
98.32%

3.3:84. 柱状图中最大的矩形 - 力扣(LeetCode)

class Solution {public int largestRectangleArea(int[] heights) {//现在思考一个问题,就是这个的时间复杂度是O(N)int[] stack =new int[heights.length];int r=0;int cur=0;int ans=0;for(int i=0;i<heights.length;i++){while(r>0&&heights[stack[r-1]]>=heights[i]){cur =stack[--r];int left=r>0?stack[r-1]:-1;int right=i;ans=Math.max((right-left-1)*heights[cur],ans);}stack[r++] = i; // 把当前柱子的索引入栈}while(r>0){cur =stack[--r];int left=r>0?stack[r-1]:-1;int right=heights.length;ans=Math.max((right-left-1)*heights[cur],ans);}return ans;}
}

3.4:85. 最大矩形 - 力扣(LeetCode)

思路:

首先在我们的思路里面,以每一层为底去计算面积
但是必须是连续的才会是累计关系,如果是零的话就直接为0  
解释一下为什么是这样的,因为如果是0的话,你这里是组不成长方形的,所以你的结果就会和你以前计算的值相同,在这里算的话就是零,但是这是零的话,对别的点是否有影响呢,当然是不会有的
因为你这里是零,谁也不能在这里创建长方形了,不会由影响
用到的技巧是压缩数组
class Solution {public int maximalRectangle(char[][] matrix) {int ans = 0;int[] arr = new int[matrix[0].length]; // 初始化高度数组for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[0].length; j++) {// 更新 arr 数组:如果是 '1' 则增加高度,否则重置为 0arr[j] = (matrix[i][j] == '1') ? arr[j] + 1 : 0;}ans = Math.max(getSum(arr), ans); // 更新答案}return ans;}private int getSum(int[] heights){//现在思考一个问题,就是这个的时间复杂度是O(N)int[] stack =new int[heights.length];int r=0;int cur=0;int ans=0;for(int i=0;i<heights.length;i++){while(r>0&&heights[stack[r-1]]>=heights[i]){cur =stack[--r];int left=r>0?stack[r-1]:-1;int right=i;ans=Math.max((right-left-1)*heights[cur],ans);}stack[r++] = i; // 把当前柱子的索引入栈}while(r>0){cur =stack[--r];int left=r>0?stack[r-1]:-1;int right=heights.length;ans=Math.max((right-left-1)*heights[cur],ans);}return ans;}
}

相关文章:

大厂高频算法考点--单调栈

什么是单调栈&#xff1a; 单调栈就是借助一个栈&#xff0c;在仅仅使用当前栈的条件下&#xff0c;时间复杂度是N&#xff08;n&#xff09;,将每个节点最有离这他最近的大于或者是小于的数据返回&#xff0c;将已知数组的元素放到栈里。再自我实现的代码里面我们使用数组实现…...

Unity使用Git及GitHub进行项目管理

git: 工作区,暂存区(存放临时要存放的内容),代码仓库区1.初始化 git init 此时展开隐藏项目,会出现.git文件夹 2.减小项目体积 touch .gitignore命令 创建.gitignore文件夹 gitignore文件夹的内容 gitignore中添加一下内容 # This .gitignore file should be place…...

如何将本地 Node.js 服务部署到宝塔面板:完整的部署指南

文章简介&#xff1a; 将本地开发的 Node.js 项目部署到线上服务器是开发者常见的工作流程之一。在这篇文章中&#xff0c;我将详细介绍如何将本地的 Node.js 服务通过宝塔面板&#xff08;BT 面板&#xff09;上线。宝塔面板是一个强大的服务器管理工具&#xff0c;具有简洁的…...

SpringBoot项目启动报错:命令行太长解决

文章目录 SpringBoot项目启动报错&#xff1a;命令行太长解决1. 第一种方法1. 第二种方法1-1 旧版本Idea1-2 新版本Idea 3. 重新启动SpringBoot项目即可解决 SpringBoot项目启动报错&#xff1a;命令行太长解决 报错信息&#xff1a; 1. 第一种方法 1. 第二种方法 找到项目…...

使用Docker启动的Redis容器使用的配置文件路径等问题以及Python使用clickhouse_driver操作clickhouse数据库

一、使用Docker启动的Redis容器使用的配置文件路径等问题 1.docker启动的redis使用的配置文件路径是什么 使用docker搭建redis服务&#xff0c;本身redis启动的时候可以指定配置文件的&#xff0c; redis-server /指定配置文件路径/redis.conf。 但手上也没有一个redis配置文件…...

硬盘格式化后能恢复数据吗?4款好用的数据恢复软件,格式化后也能安心

咱们今天来谈谈一个挺烦人的问题——硬盘格式化后能恢复数据吗&#xff1f;别担心&#xff0c;能的&#xff01;只要你用对方法&#xff0c;就算硬盘被清空了&#xff0c;那些重要文件还是能找回来的。下面&#xff0c;我就给你们介绍几款超给力的数据恢复软件&#xff0c;让你…...

【选择C++游戏开发技术】

在选择C游戏开发技术时&#xff0c;以下几个因素是需要考虑的&#xff1a; 1. 游戏类型&#xff1a;不同类型的游戏可能需要不同的技术。例如&#xff0c;2D游戏通常采用基于精灵的引擎&#xff0c;而3D游戏通常采用基于物理模拟的引擎。根据游戏类型选择适合的技术是很重要的…...

Oracle数据库系统表空间过大,清理SYSTEM、SYSAUX表空间

一.前言 在oracle数据库中&#xff0c;system为系统表空间&#xff0c;存放着一些我们经常用到的系统表和视图&#xff0c;sysaux为辅助表空间&#xff0c;辅助着系统表空间。这两个表空间不宜添加数据文件&#xff0c;会使系统表空间过于臃肿&#xff0c;从而影响数据库的使用…...

LaTeX参考文献工具和宏包bibmap项目简介

LaTeX参考文献工具和宏包bibmap项目简介 LaTeX 中的参考文献生成方式主要有三种&#xff1a;第一种是手动写thebibliography环境的&#xff0c;第二种事基于bibtex程序的&#xff0c;第三种则是基于biblatex宏包和biber程序的。本文介绍的bibmap项目则提供了第四种方法。目前b…...

微软的 Drasi:一种轻量级的事件驱动编程方法

微软的开源数据变化处理平台有望提供一种全新的方式来构建和管理可产生持续事件流的云应用程序。 Microsoft Azure 孵化团队是微软超大规模云中比较有趣的组成部分之一。它介于传统软件开发团队和研究组织之间&#xff0c;致力于构建大规模分布式系统问题的解决方案。 这些解决…...

vue3 笔记-插槽

结构类似的模块&#xff0c;我们可以考虑用插槽&#xff0c;以便后续复用&#xff1a; 代码&#xff1a; 1.插槽 <script setup> defineProps({title: {required: true,type: String},number: {required: true,type: Number} }) </script><template><d…...

C# 字符串常用方法

文章目录 Length&#xff1a;获取字符串中字符的个数&#xff08;不包括末尾的空字符&#xff09;ToLower() 和 ToUpper()&#xff1a;将字符串转换为小写或大写形式Substring(int startIndex, int length)&#xff1a;从指定索引开始截取指定长度的子字符串Remove(int startIn…...

字节跳动青训营——入营考核解答(持续更新中~~~)

考核内容&#xff1a; 在指定的题库中自主选择不少于 15 道算法题并完成解题&#xff0c;其中题目难度分配如下&#xff1a; 简单题不少于 10 道中等题不少于 4 道困难题不少于 1 道 解答代码 8.进制求和转换&#xff08;难&#xff09; 代码实现&#xff1a; import jav…...

JavaWeb合集15-Apache POI

十五、Apache POI Apache POI是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是&#xff0c;我们可以使用POI在Java 序中对Miscrosoft Office各种文件进行读写操作。一般情况下&#xff0c;POI都是用于操作Excel文件。 使用场景&#xff1a;银行网银系统导出交…...

Threejs 实现3D 地图(01)创建基本场景

"d3": "^7.9.0", "three": "^0.169.0", "vue": "^3.5.10" <script setup> import { onMounted,ref } from vue import * as THREE from three import * as d3 from "d3"; //莫开托坐标 矫正地图…...

snmpdelta使用说明

1.snmpdelta介绍 snmpdelta命令是用来获取下一个节点的OID的值。 2.snmpdelta安装 1.snmpdelta安装 命令: yum -y install net-snmp net-snmp-utils [root@logstash ~]# yum -y install net-snmp net-snmp-utils Loaded plugins: fastestmirror Loading mirror speeds f…...

Hadoop集群安装

集群规划 node01node02node03角色主节点从节点从节点NameNode√DataNode√√√ResourceManager√NodeManager√√√SecondaryNameNode√Historyserver√ 上传安装包到node01 解压到指定目录 tar -zxvf /bigdata/soft/hadoop-3.3.3.tar.gz -C /bigdata/server/ 创建软链接 cd…...

VuePress集成到Vue项目的方法

VuePress 可以作为一个独立的静态站点生成器来使用&#xff0c;也可以集成到现有的 Vue 项目中。以下是将 VuePress 集成到 Vue 项目的几种方法&#xff1a; 1. 作为本地依赖集成 如果你想在现有的 Vue 项目中使用 VuePress 来管理文档&#xff0c;你可以将 VuePress 安装为本…...

【ROS】ROS局域网下多机通讯方法

最近工作中需要用到多机通讯&#xff0c;这里稍微总结一下使用方法。 目录 一、网络配置 二、修改两个设备的hosts文件 三、修改两个ros设备的.bashrc 四、launch文件中给节点设定运行的设备 一、网络配置 首先确保两个ros设备连接到同一局域网下&#xff0c;然后查询两个…...

linux 系统怎么使用

Linux系统的使用涉及多个方面&#xff0c;包括文件管理、目录操作、用户管理、进程管理、网络配置等。以下是对Linux系统基础使用的详细介绍&#xff1a; 一、文件管理 查看文件和目录 ls&#xff1a;列出当前目录的内容。ls -l&#xff1a;以长格式列出当前目录的内容&#x…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...