一刷代码随想录——单调栈

news2025/5/29 6:48:39
  1. 每日温度739

题目描述:

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

class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& T) {
        // 递减栈
        stack<int> st;
        vector<int> result(T.size(), 0);
        st.push(0);
        for (int i = 1; i < T.size(); i++) {
            if (T[i] < T[st.top()]) {                       // 情况一
                st.push(i);
            } else if (T[i] == T[st.top()]) {               // 情况二
                st.push(i);
            } else {
                while (!st.empty() && T[i] > T[st.top()]) { // 情况三
                    result[st.top()] = i - st.top();
                    st.pop();
                }
                st.push(i);
            }
        }
        return result;
    }
};

  1. 下一个更大元素II 496

给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素

数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。

// 版本一
class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        // 拼接一个新的nums
        vector<int> nums1(nums.begin(), nums.end());
        nums.insert(nums.end(), nums1.begin(), nums1.end());
        // 用新的nums大小来初始化result
        vector<int> result(nums.size(), -1);
        if (nums.size() == 0) return result;

        // 开始单调栈
        stack<int> st;
        for (int i = 0; i < nums.size(); i++) {
            while (!st.empty() && nums[i] > nums[st.top()]) {
                result[st.top()] = nums[i];
                st.pop();
            }
            st.push(i);
        }
        // 最后再把结果集即result数组resize到原数组大小
        result.resize(nums.size() / 2);
        return result;
    }
};

3.下一个更大元素496

nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧第一个 比 x 大的元素。

给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。

对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。

返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        stack<int> st;
        vector<int> result(nums1.size(), -1);
        if (nums1.size() == 0) return result;

        unordered_map<int, int> umap; // key:下表元素,value:下表
        for (int i = 0; i < nums1.size(); i++) {
            umap[nums1[i]] = i;
        }
        st.push(0);
        for (int i = 1; i < nums2.size(); i++) {
            if (nums2[i] < nums2[st.top()]) {           // 情况一
                st.push(i);
            } else if (nums2[i] == nums2[st.top()]) {   // 情况二
                st.push(i);
            } else {                                    // 情况三
                while (!st.empty() && nums2[i] > nums2[st.top()]) {
                    if (umap.count(nums2[st.top()]) > 0) { // 看map里是否存在这个元素
                        int index = umap[nums2[st.top()]]; // 根据map找到nums2[st.top()] 在 nums1中的下表
                        result[index] = nums2[i];
                    }
                    st.pop();
                }
                st.push(i);
            }
        }
        return result;
    }
};

4.接雨水42

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

class Solution {
public:
    int trap(vector<int>& height) {
        int sum = 0;
        for (int i = 0; i < height.size(); i++) {
            // 第一个柱子和最后一个柱子不接雨水
            if (i == 0 || i == height.size() - 1) continue;

            int rHeight = height[i]; // 记录右边柱子的最高高度
            int lHeight = height[i]; // 记录左边柱子的最高高度
            for (int r = i + 1; r < height.size(); r++) {
                if (height[r] > rHeight) rHeight = height[r];
            }
            for (int l = i - 1; l >= 0; l--) {
                if (height[l] > lHeight) lHeight = height[l];
            }
            int h = min(lHeight, rHeight) - height[i];
            if (h > 0) sum += h;
        }
        return sum;
    }
};

动态规划

class Solution {
public:
    int trap(vector<int>& height) {
        if (height.size() <= 2) return 0;
        vector<int> maxLeft(height.size(), 0);
        vector<int> maxRight(height.size(), 0);
        int size = maxRight.size();

        // 记录每个柱子左边柱子最大高度
        maxLeft[0] = height[0];
        for (int i = 1; i < size; i++) {
            maxLeft[i] = max(height[i], maxLeft[i - 1]);
        }
        // 记录每个柱子右边柱子最大高度
        maxRight[size - 1] = height[size - 1];
        for (int i = size - 2; i >= 0; i--) {
            maxRight[i] = max(height[i], maxRight[i + 1]);
        }
        // 求和
        int sum = 0;
        for (int i = 0; i < size; i++) {
            int count = min(maxLeft[i], maxRight[i]) - height[i];
            if (count > 0) sum += count;
        }
        return sum;
    }
};

单调栈

class Solution {
public:
    int trap(vector<int>& height) {
        if (height.size() <= 2) return 0; // 可以不加
        stack<int> st; // 存着下标,计算的时候用下标对应的柱子高度
        st.push(0);
        int sum = 0;
        for (int i = 1; i < height.size(); i++) {
            if (height[i] < height[st.top()]) {     // 情况一
                st.push(i);
            } if (height[i] == height[st.top()]) {  // 情况二
                st.pop(); // 其实这一句可以不加,效果是一样的,但处理相同的情况的思路却变了。
                st.push(i);
            } else {                                // 情况三
                while (!st.empty() && height[i] > height[st.top()]) { // 注意这里是while
                    int mid = st.top();
                    st.pop();
                    if (!st.empty()) {
                        int h = min(height[st.top()], height[i]) - height[mid];
                        int w = i - st.top() - 1; // 注意减一,只求中间宽度
                        sum += h * w;
                    }
                }
                st.push(i);
            }
        }
        return sum;
    }
};

5.柱形图中最大的矩形

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

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

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int sum = 0;
        for (int i = 0; i < heights.size(); i++) {
            int left = i;
            int right = i;
            for (; left >= 0; left--) {
                if (heights[left] < heights[i]) break;
            }
            for (; right < heights.size(); right++) {
                if (heights[right] < heights[i]) break;
            }
            int w = right - left - 1;
            int h = heights[i];
            sum = max(sum, w * h);
        }
        return sum;
    }
};

动态规划

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        vector<int> minLeftIndex(heights.size());
        vector<int> minRightIndex(heights.size());
        int size = heights.size();

        // 记录每个柱子 左边第一个小于该柱子的下标
        minLeftIndex[0] = -1; // 注意这里初始化,防止下面while死循环
        for (int i = 1; i < size; i++) {
            int t = i - 1;
            // 这里不是用if,而是不断向左寻找的过程
            while (t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t];
            minLeftIndex[i] = t;
        }
        // 记录每个柱子 右边第一个小于该柱子的下标
        minRightIndex[size - 1] = size; // 注意这里初始化,防止下面while死循环
        for (int i = size - 2; i >= 0; i--) {
            int t = i + 1;
            // 这里不是用if,而是不断向右寻找的过程
            while (t < size && heights[t] >= heights[i]) t = minRightIndex[t];
            minRightIndex[i] = t;
        }
        // 求和
        int result = 0;
        for (int i = 0; i < size; i++) {
            int sum = heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1);
            result = max(sum, result);
        }
        return result;
    }
};

单调栈

// 版本一
class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        stack<int> st;
        heights.insert(heights.begin(), 0); // 数组头部加入元素0
        heights.push_back(0); // 数组尾部加入元素0
        st.push(0);
        int result = 0;
        // 第一个元素已经入栈,从下表1开始
        for (int i = 1; i < heights.size(); i++) {
            // 注意heights[i] 是和heights[st.top()] 比较 ,st.top()是下表
            if (heights[i] > heights[st.top()]) {
                st.push(i);
            } else if (heights[i] == heights[st.top()]) {
                st.pop(); // 这个可以加,可以不加,效果一样,思路不同
                st.push(i);
            } else {
                while (heights[i] < heights[st.top()]) { // 注意是while
                    int mid = st.top();
                    st.pop();
                    int left = st.top();
                    int right = i;
                    int w = right - left - 1;
                    int h = heights[mid];
                    result = max(result, w * h);
                }
                st.push(i);
            }
        }
        return result;
    }
};

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

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

相关文章

spring security 核心类 和请求登陆过程

核心类图2. 执行登陆 首先请求被拦截器 UsernamePasswordAuthenticationFilter 拦截 看源代码可以看出默认拦截的是 /login 请求地址 当然这个地址是可以被配置的 private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER new AntPathRequestMatche…

DFS深度优先算法 —— AcWing 842. 排列数字AcWing 843. n-皇后问题

一、了解dfs1、DFS&#xff08;Depth First Search&#xff09;DFS在我看来就是一条路走到黑&#xff0c;直到无路可走的情况下&#xff0c;才会选择回头&#xff0c;然后重新选择一条路&#xff08;官方说法即“优先考虑深度”&#xff09;整个进程反复进行直到所有节点都被访…

Allegro如何添加ICT操作指导

Allegro如何添加ICT操作指导 当PCB板需要做飞针测试的时候,通常需要在PCB设计的时候给需要测试的网络添加上ICT。 如图: Allegro支持给网络添加ICT,具体操作如下 首先在库中创建一个阻焊开窗的过孔,比如via10-ict一般阻焊开窗的尺寸比盘单边大2mil 在PCB中选择Manufacture…

Linux基础命令1(常见的系统进程、状态命令)

目录 Linux命令格式 Linux快捷按键 常用系统命令 man 查看命令的帮助信息 echo 输出信息&#xff08;将信息输出到屏幕上面&#xff09; date 查看系统的日期、时间 timedatectl 设置系统时间&#xff0c;主要是时区&…

程序环境--翻译+执行

ANSI C标准下&#xff0c;有两种程序环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。 翻译环境包括&#xff1a;预处理&#xff08;预编译&#xff09;编译汇编链接。四个步骤。 第2种是执行/运行环境&#xff0c;它用于实际执行代码。 链接…

UPC-2023新生个人训练赛第18场-Rank1

问题 B: 2的N次方 题目描述 输入n行&#xff0c;每行一个整数x&#xff0c;输出2的x次方的个位是多少&#xff1f;2的3次方表示3个2相乘&#xff0c;结果是8 输入 输入n行&#xff0c;每行一个整数x 输出 输出n行&#xff0c;每行一个整数&#xff0c;2的x次方的个位。 …

Flink CEP 在抖音电商的业务实践

摘要&#xff1a;本文整理自抖音电商实时数仓研发工程师张健&#xff0c;在 FFA 实时风控专场的分享。本篇内容主要分为四个部分&#xff1a;Flink CEP 简介业务场景与挑战解决方案实践未来展望Tips&#xff1a;点击「阅读原文」查看原文视频&演讲 ppt01Flink CEP 简介Flin…

论文投稿指南——中文核心期刊推荐(冶金工业 2)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

23种设计模式之策略模式

一、概念 就是将一系列算法封装起来&#xff0c;并使它们之间相互替换。被封装起来的算法具有独立性外部不可改变其特性。 策略模式属于对象行为模式&#xff0c;它通过对算法进行封装&#xff0c;把使用算法的责任和算法的实现分割开来&#xff0c;并委派给不同的对象对这些算…

BCN点击试剂diSulfo-Cy5-PEG3-BCN,二磺酸三聚乙二醇环丙烷环辛炔,纯度 95%+

【中文名称】二磺酸-三聚乙二醇-环丙烷环辛炔【英文名称】 diSulfo-Cy5-PEG3-BCN&#xff0c;BCN-PEG-Sulfo Cy5【CAS号】N/A【分子式】C51H68N4O12S2【分子量】993.24【基团】BCN基团【纯度】95%【规格标准】1g&#xff0c;5g&#xff0c;10g&#xff0c;包装灵活&#xff0c;…

2-ChatGPT插件到Google浏览器,并进行ChatGPT工作。

ChatGPT插件到Google浏览器&#xff0c;并进行ChatGPT工作。1&#xff0c;首先&#xff0c;在装插件ChatGPT forGoogle插件时&#xff0c;我没安装成功&#xff0c;问题是我没有区分Google浏览器和双核浏览器的差别。2&#xff0c;如何使用ChatGPT在浏览器上进行工作。1&#x…

[future 2022] 基于特征选择的DDoS攻击流分类方法

https://www.sciencedirect.com/science/article/pii/S0167739X22000474highlights•我们设计了一种特征选择方法来选择独立和相关的特征。•我们设计了一种方法来识别物联网和复杂的 DDoS 攻击流。•该体系结构在有效性和效率方面优于比较方法。摘要分布式拒绝服务 (DDoS) 攻击…

CentOS8基础篇3:使用vim编辑文档

一、vim编辑器 vim 编辑器共有三种工作模式&#xff0c;分别是命令模式、输入模式和末行模式。 〖例2.24〗使用vim编辑器创建并编辑文件hello.c。 二、查看文件内容命令 1. more/less 浏览文件全部内容 当文件内容过多时&#xff0c;可以用more或less命令来查看。 命令格式…

HTTP缓存看这一篇就够了

前言 HTTP缓存机制是优化web性能的重要手段&#xff0c;也是优化用户体验的重要一环。了解和熟悉HTTP缓存机制也成为了前端工作者必不可少的技能。 HTTP缓存是用于临时存储网页资源&#xff08;如HTML页面、图像等&#xff09;&#xff0c;以减少服务器延迟的一种技术。HTTP缓…

nim语言在不同操作系统安装

官网&#xff1a; Nim Programming Language 学习文档&#xff1a; Nim文档概述 Tutorial (part I)The Nim one deals with basics. 官方下载地址&#xff1a;Download - Nim Programming Language 目录 Mac OS Ubuntu centos Mac OS 安装语言 brew install nim 安装…

nodejs基于vue的饭店点餐外卖平台网站

本系统主要实现了管理员&#xff1a;首页、个人中心、用户管理、菜品分类管理、菜品信息管理、菜品评价管理、系统管理、订单管理,用户&#xff1a;首页、个人中心、菜品评价管理、我的收藏管理、订单管理,前台首页&#xff1a;首页、菜品信息、菜品资讯、个人中心、后台管理、…

尚医通(九)数据字典模块前后端 | EasyExcel

目录一、数据字典介绍1、什么是数据字典2、页面展示效果3、数据字典表设计4、数据分析5、根据页面效果分析数据接口二、搭建数据字典模块三、数据字典列表接口1、model模块添加数据字典实体2、添加数据字典mapper3、添加数据字典service4、添加数据字典controller四、数据字典列…

【百宝书】ChatGPT真的会成为MOSS吗?如果MOSS真的存在,地球和人类的结局会是怎么样的。

大家好&#xff0c;我是涵子&#xff0c;今天我们紧随潮流&#xff0c;聊聊ChatGPT会成为MOSS吗&#xff1f;如果MOSS真的存在&#xff0c;地球和人类的结局会是怎么样的。 本次借鉴内容&#xff1a; 程序yang - ChatGPT的火爆出圈&#xff0c;你对它有几分了解&#xff1f;_程…

【C++提高编程】map/ multimap 容器详解(附测试用例与结果图)

目录1. map/ multimap容器1.1 map基本概念1.2 map构造和赋值1.3 map大小和交换1.4 map插入和删除1.5 map查找和统计1.6 map容器排序1.7 案例-员工分组1.7.1 案例描述1.7.2 实现步骤1. map/ multimap容器 1.1 map基本概念 简介&#xff1a; map中所有元素都是pairpair中第一个…

“亚洲一号”也能上市?REITs背后的物流设施风起云涌

京东最近发生了两件大事&#xff0c;两件都与物流基础设施有关。 一件是2月8日&#xff0c;嘉实京东仓储物流封闭式基础设施证券投资基金&#xff08;简称“京东仓储REIT”&#xff09;正式登陆上交所&#xff0c;投资者获得了机会&#xff0c;去分享京东三处物流园区的收益&a…