当前位置: 首页 > 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…...

Java线程池知识点梳理

Java线程池知识点梳理 什么是线程池&#xff1f; 线程在系统中创建的成本是相对比较高的&#xff0c;所以使用”池化“的思想&#xff0c;设计线程池&#xff0c;有大量任务需要执行时&#xff0c;可以直接从线程池中使用已经创建好的线程直接去执行。减少线程的创建和销毁带…...

SFT、RLHF、DPO、IFT —— LLM 微调的进化之路_如何搭建自己的dpo

TL;DR • SFT、RLHF 和 DPO 都是先估计 LLMs 本身的偏好&#xff0c;再与人类的偏好进行对齐&#xff1b; • SFT 只通过 LLMs 生成的下一个单词进行估计&#xff0c;而 RLHF 和 DPO 通过 LLMs 生成的完整句子进行估计&#xff0c;显然后者的估计会更准确&#xff1b; • 虽然…...

CSS 选择器简单回顾

引言 当我们探讨网页设计和开发时, CSS(层叠样式表) 无疑是一个不可或缺的技术, 它使我们能够精确控制网页的外观和布局, 为用户创造出独特的视觉体验、以及良好的交互体验!! 而一个完整的 CSS 规则则是由两个主要部分组成: 选择器和声明块 那么今天我们就来盘点下常见的几种选…...

uniapp配置微信小程序分包(分包优化)

1.manifest.json中 源码视图中找到mp-weixin&#xff0c;新增代码"optimization":{"subPackages":true}&#xff0c;如下图所示 "optimization" : {"subPackages" : true } 2.pages.json中 分包内静态文件示例 "subPackages&…...

MySQL-10.DML-添加数据insert

一.DML(INSERT) -- DDL&#xff1a;数据操作语言 -- DML&#xff1a;插入数据 - insert -- 1.为tb_emp表的username&#xff0c;name&#xff0c;gender字段插入值 insert into tb_emp (username,name,gender) values (wuji,无忌,1); -- 这样会报错&#xff0c;因为create_ti…...

ARM/Linux嵌入式面经(四八):tp-link联洲国际

文章目录 1. **模电基础**:请解释共射电路的工作原理,并描述如何计算其放大倍数。工作原理放大倍数计算面试官追问及回答2. **DCDC损耗**:有哪些方法可以降低DCDC转换器的损耗?3. **示波器使用**:如何用示波器正确测量DCDC的开关纹波?4. **IIC通信**:IIC通信协议中是否需…...

代码实践篇四 形状检测与规则重建

本节内容主要涉及形状检测&#xff08;Shape Detection&#xff09;与形状重建&#xff08;Shape Reconstruction&#xff09;&#xff0c;具体算法步骤会在后续章节介绍。CGAL在6.0重点更新了形状重建部分的一些模块——动态空间分割与动态形状重建等&#xff0c;也会在后续详…...

JVM(HotSpot):GC之垃圾回收阶段

文章目录 前言一、标记清除算法(Mark Sweep)二、标记整理算法(Mark Compact)三、复制算法(Copy) 前言 标记出垃圾对象之后&#xff0c;就要进行清理。 那么&#xff0c;如何清理&#xff1f; 这里也有相应的算法。 主要有三种。 一、标记清除算法(Mark Sweep) 原理说明&…...

Go 项目如何集成类似mybatisPlus插件呢?GORM走起!!

导读&#xff1a; 在 Go 项目中&#xff0c;虽然没有像 MyBatis Plus 这样特定的 ORM 插件&#xff0c;但可以使用功能相似的 Go ORM 框架&#xff0c;比如 GORM&#xff0c;它支持链式查询、自动迁移、预加载等功能&#xff0c;与 MyBatis Plus 有相似之处。通过一些插件或扩…...

《深度学习》Dlib库 CNN卷积神经网络 人脸识别

目录 一、如何实现CNN人脸识别 1、CNN核心概念 1&#xff09;卷积层 2&#xff09;池化层 3&#xff09;激活函数 4&#xff09;全连接层 2、步骤 1&#xff09;加载预训练的人脸识别模型 2&#xff09;读取图像并检测人脸 3&#xff09;提取人脸特征向量 4&#xf…...