[算法]单调栈解法

news2024/11/15 23:34:06

目录

739. 每日温度 - 力扣(LeetCode) 

42. 接雨水 - 力扣(LeetCode)

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


739. 每日温度 - 力扣(LeetCode) 

解法:

通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了

1.在本题中,其实就是,找到一个元素右边比自己大的第一个元素,就要想到用单调栈了。

2.单调栈的原理就是,用栈来保存我们遍历过的元素,不至于我们在遍历时忘记我们之前遍历过的较小的元素,当我们找到较大的元素时,我们就可以从栈口从小到大的找回之前小于它的元素(多一个栈的空间,可以让时间复杂度降到O(n))。

代码:

class Solution 
{
public:
    vector<int> dailyTemperatures(vector<int>& temperatures)
    {
        //单调栈
        stack<int> st;
        st.push(0);
        vector<int> ret(temperatures.size(), 0);
        for (int i = 1; i < temperatures.size(); i++)
        {
            //遍历元素小于栈口元素的(下标入栈)
            if (temperatures[i] <= temperatures[st.top()])
            {
                st.push(i);
            }
            else//大于栈口元素
            {
                //栈里找小于遍历元素的
                while (!st.empty() && temperatures[i] > temperatures[st.top()])
                {
                    int tmp = st.top();
                    st.pop();
                    ret[tmp] = i - tmp;
                }
                //遍历元素入栈
                st.push(i);
            }
            
        }
        return ret;
    }
};

42. 接雨水 - 力扣(LeetCode)

解法:

通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。

1.本题目中,其实就是要找到一个元素右边第一个比自己大的元素,再和自己上一个元素组成凹槽,计算凹槽大小。

2.单调递增栈

class Solution
{
public:
	int trap(vector<int>& nums)
	{
		//单调栈-递增栈
		stack<int> st;
		st.push(0);
		int ret = 0;
		for (int i = 1; i < nums.size();i++)
		{
			if (nums[i] <= nums[st.top()]) st.push(i);//遍历元素小于等于栈口元素入栈
			else
			{
				while (!st.empty() && nums[st.top()] < nums[i])
				{
					int mid = st.top();
					st.pop();//弹出
					if(!st.empty())//前面弹出的一个有可能是最后一个,所以要探空
						ret += (min(nums[i], nums[st.top()])-nums[mid]) * (i - st.top()-1);//计算凹槽处的雨水数量
				}
				st.push(i);
			}
		}
		return ret;
	}
};

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

解法:

上面接雨水那题是找每个柱子左右两边第一个大于该柱子高度的柱子,而本题是找每个柱子左右两边第一个小于该柱子的柱子。

1.因为是找矩形,较小元素限制了矩形的大小,因此需要找到一个元素两边比自己小的元素,找比自己小的元素就需要用单调递减栈了。

2.遍历元素比栈口大的入栈,当遇到第一个比栈口大的,栈口元素设置为mid,新栈口元素和遍历元素i就是两边比mid小的元素,以nums[i]为基准高h,求矩形大小。

代码:

class Solution {
public:
    int largestRectangleArea(vector<int>& nums)
    {
        //单调栈-递减栈
        stack<int> st;
        int ret = 0;
        //首尾加0
        nums.insert(nums.begin(), 0);
        nums.insert(nums.end(), 0);
        
        st.push(0);
        st.push(1);

        for (int i = 1; i < nums.size(); i++)
        {
            //遍历元素比栈口元素大的入栈
            if (nums[i] >= nums[st.top()])
            {
                st.push(i);
            }
            else
            {
                while (st.size()>1 && nums[i] < nums[st.top()])
                {
                    int mid = st.top();//以mid为基准
                    st.pop();
                    int left = st.top();
                    int right = i;
                    int h = nums[mid];
                    int w = right - left - 1;
                    ret = max(h * w, ret);
                }
                st.push(i);
            }
        }
        return ret;
    }
};

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

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

相关文章

Ubuntu: 配置OpenCV环境

从从Ubuntu系统安装opencv_ubuntu安装opencv-CSDN博客文章浏览阅读2.3k次&#xff0c;点赞4次&#xff0c;收藏14次。开源计算机视觉(OpenCV)是一个主要针对实时计算机视觉的编程函数库。OpenCV的应用领域包括:2D和3D功能工具包、运动估计、面部识别系统、手势识别、人机交互、…

2024 高教社杯 数学建模国赛 (C题)深度剖析|农作物的种植策略|数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题&#xff01; CS团队倾注了大量时间和心血&#xff0c;深入挖掘解…

数学专题.

数论 1.判断质数 定义&#xff1a;在大于1的整数中&#xff0c;如果只包含1和本身这两个约数&#xff0c;就称为质数or素数 Acwing 866.试除法判断质数 2.预处理质数&#xff08;筛质数&#xff09; Acwing 868.筛质数 3.质因数分解 Acwing 867.分解质因数 4.阶乘分解 5.因…

2024最新软件测试面试题(附答案)来测试下你的水平

1、软件测试的目的是&#xff08; &#xff09; A、试验性运行软件 B、发现软件错误 C、证明软件正确 D、找出软件中全部错误 【答案】B 2、下面说法正确的是( ) A、经过测试没有发现错误说明程序正确 B、测试的目标是为了证明程序没有错误 C、成功的测试是发现了迄今…

数字货币是怎么回事什么是数字货币

数字货币的定义 数字货币是一种基于密码学原理的数字形式表示的货币&#xff0c;通过特定的加密算法和分布式账本技术实现安全交易和流通。它不像传统货币那样具有实体形态&#xff0c;而是以电子方式存在。数字货币可以通过互联网进行转账和交易&#xff0c;通常依赖区块链等分…

OPC DA

默认端口号: TCP 135 参考https://wenku.baidu.com/view/8f2b18a229f90242a8956bec0975f46527d3a7e4.html?_wkts_1725526157944&bdQuery%E6%9F%A5%E7%9C%8B%E8%A5%BF%E9%97%A8%E5%AD%90opcDA%E7%AB%AF%E5%8F%A3%E5%8F%B7 OPC DA ,OPC UA简介https://www.cnblogs.com/mi…

Qt 应用程序主界面

主要窗口类的概述 这些类提供了典型现代主应用程序窗口所需的一切&#xff0c;如主窗口本身、菜单和工具栏、状态栏等。 QAction 可以插入小部件的抽象用户界面操作 QActionGroup 将动作组合在一起 QDockWidget 小部件&#xff0c;可以停靠在QMainWindow中&#xff0c;也可以作…

springboot+vue+mybatis计算机毕业设计音乐播放系统+PPT+论文+讲解+售后

音乐播放系统的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品&#xff0c;体验高科技时代带给人们的方便&#xff0c;同时也能让用户体会到与以往常规产品不同的体验风格。 与安卓&#xff0c;iOS相比较起来&#xff0c;音乐…

【JVM】JVM简介|运行流程|内存划分

目录 一、JVM简介 二、JVM运行流程 三、JVM运⾏时数据区&#xff08;内存划分&#xff09; 3.1 堆&#xff08;线程共享&#xff09; 3.2 栈 3.3 元数据区&#xff08;方法区&#xff09;&#xff08;线程共享&#xff09; 3.4 程序计数器&#xff08;线程私有&#xff0…

【学习笔记】5G-A时代物联网应用及策略研究

摘要 海量物联网通信是5G典型应用场景之一&#xff0c;为了实现蜂窝网的全场景物联能力&#xff0c;需要更多的场景化技术&#xff0c;5G-A引入了RedCap&#xff08;5G Reduced Capability&#xff09;和Passive IoT。其中&#xff0c;RedCap降低了设备复杂性及成本&#xff0…

js混淆保护在线工具开源项目大全

具体前往&#xff1a;js代码混淆加密保护工具&开源项目大全

指针复习--(笔记整理)

之前出的有指针合集在博客&#xff0c;最近要备考计算机二级&#xff0c;所以复习了一下&#xff0c;有一些容易遗忘的点整理了一下&#xff0c;大家可以有针对性的看一看&#xff0c;后续刷二级真题的时候也会进行题目代练&#xff0c;可以下收藏起来。记得先赞&#xff0c;祝…

力扣96-不同的二叉搜索树(Java详细题解)

题目链接&#xff1a;96. 不同的二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 前情提要&#xff1a; 因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。 dp五部曲。 1.确定dp数组和i下标的含义。 2.确定递推公式。 3.dp初始化。 4.确定dp的遍历顺序。 …

高并发内存池(一):项目介绍与定长内存池的实现

目录​​​​​​​ 项目介绍 池化技术 内存池 内存碎片 malloc工作原理 定长内存池 申请内存 释放内存 定位new VirtualAlloc函数 封装VirtualAlloc 定长内存池的最终代码 项目介绍 项目原型&#xff1a;goole的开源项目tcmalloc&#xff08;Thread-Caching Mal…

一种极简的余弦定理证明方法

余弦定理的证明方法有很多种&#xff0c;这里介绍一种极简的证明方法。该方法是本人在工作中推导公式&#xff0c;无意中发现的。证明非常简单&#xff0c;下面简单做下记录。   如上图为任意三角形ABC&#xff0c;以点C为原点&#xff0c;建立直角坐标系&#xff08;x轴方向…

【网络编程通关之路】 Udp 基础回显服务器(Java实现)及你不知道知识原理详解 ! ! !

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

vue3中ref自动解包

1.模板中使用 ref 类型的数据&#xff0c;会自动解包&#xff0c;注意需要是顶级的ref <template> <!-- 自动解包--><div>{{ name }}</div> </template><script setup> import { ref} from vue const name ref(hello) </script>下…

com.alibaba.fastjson.JSONArray循环引用导致{“$ref“:“$[0]“}

发一个库存~ 在for循环中将对象add到.JSONArray中&#xff0c;arr.toJSONString()&#xff0c;输出的结果如下&#xff1a; [{"sex":"男","age":"10","name":"张三"},{"$ref":"$[0]"},{&quo…

Java synchronized 原理

Synchronized使用 synchronized关键字可使用在方法上或代码块上表示一段同步代码块&#xff1a; public class SyncTest {public void syncBlock(){synchronized (this){System.out.println("hello block");}}public synchronized void syncMethod(){System.out.pr…

小白入门LLM大模型最牛X教程------上交《动手学大模型应用开发》!

本项目是一个面向小白开发者的大模型应用开发教程&#xff0c;旨在结合个人知识库助手项目&#xff0c;通过一个课程完成大模型开发的重点入门&#xff0c;涵盖了大模型应用开发的方方面面&#xff0c;主要包括&#xff1a; 教程一共有七章内容&#xff1a; 《动手学大模型》…