单调栈问题

news2024/11/26 4:45:52

原理

单调栈的核心原理是:在栈内保持元素的单调性(递增或递减)

单调递增栈

用于处理“下一个更小的元素”问题。当新元素比栈顶元素小或等于时,直接入栈;否则,一直从栈顶弹出元素,直到栈顶元素小于新元素或栈为空。

单调递减栈:

用于处理“下一个更大的元素”问题。当新元素比栈顶元素大时,一直从栈顶弹出元素,直到栈顶元素大于新元素或栈为空,然后将新元素入栈。

核心代码框架

#include <vector>
#include <stack>
using namespace std;

vector<int> nextGreaterElement(vector<int>& nums) {
    int n = nums.size();
    vector<int> res(n, -1);  // 默认值为-1,表示没有找到
    stack<int> stk;          // 用于存储元素索引的单调栈

    for (int i = 0; i < n; i++) {
        // 维护栈的单调递减性
        while (!stk.empty() && nums[stk.top()] < nums[i]) {
            int idx = stk.top(); // 栈顶元素索引
            stk.pop();
            res[idx] = nums[i]; // 找到了下一个更大的元素
        }
        stk.push(i); // 入栈当前元素索引
    }

    return res;
}

739. 每日温度

在这里插入图片描述

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        int n = temperatures.size();
        vector<int> res(n,0);
        stack<int>stk;

        for(int i = 0;i<n;i++){
            // 递增
            while(!stk.empty() && temperatures[stk.top()]<temperatures[i]){
                int index = stk.top(); // 栈顶元素
                stk.pop();
                res[index] = i-index;
                //res[index] = temperatures[i];
            }
            stk.push(i);
        }
        for(int i = 0;i<n;i++){
            cout<<res[i]<<endl;
        }
        return res;
    }
};

496.下一个更大元素 I

在这里插入图片描述
思路:暴力法

直接足步循环
先找到和 nums1 对应的 nums2 数,找到后,在循环找更大的,找到就退出

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        int m = nums2.size();

        vector<int> res (n,-1); // -1代表没找到
        stack<int>stk;

        for(int i = 0;i<n;i++){
            int j = 0;
            while(nums1[i] != nums2[j]){
                j++;
            }
            for(int k = j+1; k<m;k++){
                if(nums2[k]>nums1[i]){
                    res[i] = nums2[k];
                    break;
                }
            }
        }
        return res;
    }
};

思路二:单调栈

我们可以先对 nums2 进行单调栈,找到他每个元素的的下一个更大的数
再根据 nums1 创建数组

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        int m = nums2.size();

        unordered_map<int, int> nxetnum;

        vector<int> res (n,-1); // -1代表没找到
        stack<int>stk;

        // 遍历 nums2
        for(int num : nums2){
            while(!stk.empty()&& stk.top()<num){
                nxetnum[stk.top()] = num;
                stk.pop();
            }
            stk.push(num);
        }

        // 如果没有更大元素,则对应结果为 -1;
        while(!stk.empty()){
            nxetnum[stk.top()] = -1;
            stk.pop();
        }

        // 从nums1 中查找对应的;
        for(int i = 0;i<n;i++){
            res[i] = nxetnum[nums1[i]];
        }
        
        return res;
    }
};

503.下一个更大元素II

在这里插入图片描述
思路:

因为可以循环,直接将数组进行拼接,这样就破解循环问题了,就如同前面的每日温度问题了

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        int n = nums.size();
        vector<int>realnums;
        // 暴力拼接
        for(int i = 0; i<2;i++){
            for(int num:nums){
                realnums.push_back(num);
            }
        }

        vector<int> res(2*n,-1);
        stack<int>stk;
        for(int i = 0;i<realnums.size();i++){
            while(!stk.empty() && realnums[stk.top()]<realnums[i]){
                int index = stk.top();
                stk.pop();
                res[index] = realnums[i];
            }
            stk.push(i);
        }

        vector<int>resnum;
        resnum.insert(resnum.end(),res.begin(),res.begin()+n);
        return resnum;

    }
};

代码优化一下:

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        int n = nums.size();
        vector<int>realnums(n,-1);

        stack<int>stk;

        for(int i = 0 ;i<2*n;i++){
            int num = nums[i % n];
            while(!stk.empty() && nums[stk.top()] <num){
                int index = stk.top();
                stk.pop();
                realnums[index]  = num;
            }
            if(i<n){
                stk.push(i);
            }
        }
        return realnums;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1669384.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

会声会影2024中文汉化补丁器附免费激活码序列号

会声会影是一款由加拿大Corel公司发布的视频编辑软件&#xff0c;它以其功能丰富和用户友好的界面而闻名。会声会影2024是该系列的最新版本&#xff0c;它不仅继承了之前版本的强大功能&#xff0c;还引入了一系列新的特性和工具&#xff0c;使得视频编辑更加简单、高效且富有创…

【简单讲解下Fine-tuning BERT】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

【图解计算机网络】TCP 重传、滑动窗口、流量控制、拥塞控制

TCP 重传、滑动窗口、流量控制、拥塞控制 TCP 重传超时重传快速重传 滑动窗口流量控制拥塞控制慢启动拥塞避免拥塞发生快速恢复 TCP 重传 TCP重传是当发送的报文发生丢失的时候&#xff0c;重新发送丢失报文的一种机制&#xff0c;它是保证TCP协议可靠性的一种机制。 TCP重传…

【Oracle篇】rman物理备份工具的基础理论概述(第一篇,总共八篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&am…

试衣不再有界:Tunnel Try-on开启视频试衣应用新纪元

论文&#xff1a;https://arxiv.org/pdf/2404.17571 主页&#xff1a;https://mengtingchen.github.io/tunnel-try-on-page/ 一、摘要总结 随着虚拟试衣技术的发展&#xff0c;消费者和时尚行业对于能够在视频中实现高质量虚拟试衣的需求日益增长。这项技术允许用户在不实际穿…

云计算十三课

centos安装 点击左上角文件 点击新建虚拟机 点击下一步 点击稍后安装操作系统&#xff0c;下一步 选择Linux&#xff08;l&#xff09;下一步 设置虚拟机名称 点击浏览选择安装位置 新建文件夹设置名称不能为中文&#xff0c;点击确定 点击下一步 设置磁盘大小点击下一步…

修改MTU值解决Linux下运行top命令卡死问题

上周明月的Linux服务器上运行top命令总是莫名的出现卡死现象&#xff0c;甚至是CtrlC都无法终止进程&#xff0c;今天终于抽空找到了解决办法&#xff0c;原来是需要修改Linux的MTU值&#xff0c;将服务器操作系统数据包调小&#xff0c;加上VxLAN数据包小于1500即可。 top命令…

HCIP【BGP综合实验】

目录 一、实验拓扑图&#xff1a; 二、实验要求&#xff1a; 三、实验思路&#xff1a; 四、实验步骤&#xff1a; 1、进行网段的子网划分&#xff08;整个实验总共有19条网段&#xff09;&#xff1a; (1)首先&#xff0c;根据实验要求&#xff0c;将172.16.0.0/16全部划…

英伟达发布AM-RADIO高效视觉基础模型,推理速度提升6倍,性能超CLIP、DINOv2、SAM

前言 近年来&#xff0c;视觉基础模型 (VFM) 在众多下游任务中取得了巨大成功&#xff0c;例如图像分类、目标检测和图像生成等。然而&#xff0c;现有的 VFM 通常专注于特定领域&#xff0c;例如 CLIP 擅长零样本视觉语言理解&#xff0c;DINOv2 擅长语义分割&#xff0c;SAM…

C控制语句:分支和跳转

1.1if语句 //colddays.c --找出0摄氏度以下的天数占总天数的百分比 #include <stdio.h>int main(void) {const int FREEZING 0;float temperature;int cold_days 0;int all_days 0;printf("Enter the list of daily low temperature.\n");printf("Use…

C++内存管理new/delete和new[ ]/delete[ ]

1.c/c内存分布 首先看一段代码 int globalVar 1; static int staticGlobalVar 1; void Test() { static int staticVar 1; int localVar 1; int num1[10] { 1, 2, 3, 4 }; char char2[] "abcd";const char* pChar3 "abcd"; //这里不加const会导致…

整理好的宁夏光伏发电数据集(2007-2020年)

1、包含指标&#xff1a;采样结束时刻、采样起始时刻、时间间隔、气温、方位角、云层不透明度、露点温度、DHI&#xff08;太阳散射辐射指数&#xff09;、DNI&#xff08;太阳直接辐射指数&#xff09;、GHI&#xff08;太阳总水平辐射&#xff09;、GTI&#xff08;固定倾角辐…

06-Fortran基础--Fortran模块化编程

06-Fortran基础--Fortran模块化编程 1 模块的定义和使用2 接口和模块间通信3 模块化编程的优势&#xff1a;4 模块使用示例5 结语 Fortran的模块化编程是一种组织和管理代码的方法&#xff0c;它包括模块的定义和使用、接口和模块间通信以及模块化编程的优势。 1 模块的定义和…

外网如何访问内网?快解析

由于公网IP资源短缺&#xff0c;我们的电脑大多处于内网环境&#xff0c;如何在外网访问内网电脑&#xff0c;成为一个令人头疼的问题&#xff0c;下面我给大家推荐一个非常实用的方法。 1&#xff1a;访问快解析下载安装快解析服务器 2&#xff1a;运行软件&#xff0c;点击“…

匿名管道及其应用

目录 一、什么是匿名管道&#xff1f; 三、创建与使用匿名管道 三、匿名管道的特点 匿名管道的四种情况 匿名管道的五种特性 四、匿名管道的实践应用---进程池 在编程的世界中&#xff0c;匿名管道是一种非常重要的通信机制。今天&#xff0c;让我们一起来深入探讨一下匿…

Spring WebFlux-响应式编程-019

&#x1f917; ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱&#xff0c;有温度&#xff0c;有质量&#xff0c;有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace The Nex…

Redis-发布与订阅

发布与订阅 什么是发布与订阅 Redis 发布订阅 (pub/sub) 是一种消息通信模式&#xff1a;发送者 (pub) 发送消息&#xff0c;订阅者 (sub) 接收消息。 Redis 客户端可以订阅任意数量的频道。 Redis的发布与订阅 客户端订阅频道 当给这个频道发送消息后&#xff0c;消息就会…

Java | Leetcode Java题解之第86题分隔链表

题目&#xff1a; 题解&#xff1a; class Solution {public ListNode partition(ListNode head, int x) {ListNode small new ListNode(0);ListNode smallHead small;ListNode large new ListNode(0);ListNode largeHead large;while (head ! null) {if (head.val < x…

LwIP 之九 详解 UDP RAW 编程、示例、API 源码、数据流

我们最为熟知的网络通信程序接口应该是 Socket。LwIP 自然也提供了 Socket 编程接口,不过,LwIP 的 Socket 编程接口都是使用最底层的接口来实现的。我们这里要学习的 UDP RAW 编程则是指的直接使用 LwIP 的最底层 UDP 接口来直接实现应用层功能。这里先来一张图,对 LwIP 内部…

Java泛型,这一篇就够了

1. 为什么我们需要泛型 现实世界中我们经常遇到这样一种情况&#xff0c;同一个算法/数据结构适用于多种数据类型&#xff0c;我们不想为每一种类型单独写一个实现。举个例子来说&#xff0c;我们有一个Pair类型&#xff0c;存储key、value两个字段&#xff0c;代码如下。如果…