【算法日志】单调栈: 单调栈简介及其应用

代码随想录刷题60Day


目录

单调栈简介

单调栈的应用

下次更高温

下一个更大元素1

下一个更大元素2

接雨水

柱状图中最大矩形


单调栈简介

单调栈(Monotonic Stack)是一种特殊的栈数据结构,它满足元素的单调性,这种单调性需要自己建立和维护。单调栈分为单调递增栈和单调递减栈两种类型。

单调递增栈的特点是栈内元素从栈底到栈顶依次递增,而单调递减栈则是栈内元素从栈底到栈顶依次递减。

单调栈的主要应用是解决一些与找到元素的下一个更大或更小相关的问题。它通过维护一个递增或递减的栈,可以在常数时间内找到每个元素的下一个更大或更小的元素。

单调栈的基本操作包括:

入栈:将元素压入栈顶,同时保持栈的单调性。

出栈:从栈顶移除元素。

查找:检查栈顶元素,获取当前元素的下一个更大或更小的元素。

单调栈的应用

下次更高温

cpp 复制代码
    vector<int> dailyTemperatures(vector<int>& temperatures) 
	{
		int size = temperatures.size();
		vector<int> result(size, 0);
		stack<int> stack;
		stack.push(0);
		for (int i = 1; i < size; ++i)
		{
			int j = stack.top();
			if (temperatures[i] > temperatures[j])
			{
				while (!stack.empty() && temperatures[i] > temperatures[j])
				{
					result[j] = i - j;
					stack.pop();
					if (!stack.empty())j = stack.top();
				}
			}
			stack.push(i);
		}
		return result;
	}

下一个更大元素1

cpp 复制代码
	vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) 
	{
		int size1 = nums1.size();
		int size2 = nums2.size();
		unordered_map<int, int> umap;
		stack<int> stack;
		vector<int> result;
		stack.push(0);
		for (int i = 1; i < size2; ++i)
		{
			int j = stack.top();
			if (nums2[j] < nums2[i])
			{
				while (!stack.empty() && nums2[j] < nums2[i])
				{
					umap.insert(pair<int, int>(nums2[j], nums2[i]));
					stack.pop();
					if (!stack.empty())j = stack.top();
				}
			}
			stack.push(i);
		}
		for (int i = 0; i < size1; ++i)
		{
			if (umap.find(nums1[i]) != umap.end())
				result.push_back(umap[nums1[i]]);
			else
				result.push_back(-1);
		}
		return result;
	}

下一个更大元素2

cpp 复制代码
	vector<int> nextGreaterElements(vector<int>& nums) 
	{
		int size = nums.size();
		vector<int> dp(size, -1);
		stack<int> mystack;
		mystack.push(0);
		for (int i = 1; i < size; ++i)
		{
			if (nums[i] > nums[mystack.top()])
			{
				while (!mystack.empty() && nums[i] > nums[mystack.top()])
				{
					dp[mystack.top()] = nums[i];
					if (!mystack.empty())mystack.pop();					
				}
			}
			mystack.push(i);
		}
		for (int i = 0; i < size; ++i)
		{
			if (nums[i] > nums[mystack.top()])
			{
				while (!mystack.empty() && nums[i] > nums[mystack.top()])
				{
					dp[mystack.top()] = nums[i];
					if (!mystack.empty())mystack.pop();					
				}
			}
			mystack.push(i);
		}
		return dp;
	}

接雨水

cpp 复制代码
	int trap(vector<int>& h)
	{
		if (h.size() < 3)return 0;
		stack<int> mystack;
		int result = 0;
		mystack.push(0);
		for (int i = 1; i < h.size(); ++i)
		{
			if (h[mystack.top()] > h[i])
				mystack.push(i);
			else if (h[mystack.top()] < h[i])
			{
				while (!mystack.empty() && h[mystack.top()] < h[i])
				{
					int mid = mystack.top();
					mystack.pop();
					if (!mystack.empty())
						result += (min(h[mystack.top()], h[i]) - h[mid]) * (i - mystack.top() - 1);				
				}
				if (!mystack.empty() && h[mystack.top()] == h[i])
					mystack.pop();
				mystack.push(i);
			}
			else
			{
				mystack.pop();
				mystack.push(i);
			}
		}
		return result;
	}

柱状图中最大矩形

cpp 复制代码
	int largestRectangleArea(vector<int>& h) 
	{
		h.push_back(0);
		int size = h.size();
		stack<int> mystack;
		int result = h[0];
		mystack.push(0);
		for (int i = 1; i < size; ++i)
		{
			if (h[i] == h[mystack.top()])
			{
				mystack.pop();
			}
			else if (h[i] < h[mystack.top()])
			{
				int mid, left;
				while (!mystack.empty() && h[i] < h[mystack.top()])
				{
					mid = mystack.top();
					mystack.pop();
					if (!mystack.empty())
						left = mystack.top();
					else
						left = -1;
					result = max(result, (i - left - 1) * h[mid]);
				}
			}
			mystack.push(i);
		}
		return result;
	}
相关推荐
闻缺陷则喜何志丹14 分钟前
【前后缀分解 排序】B4274 [蓝桥杯青少年组省赛 2023] 数字游戏|普及+
c++·蓝桥杯·排序·洛谷·前后缀分解
m0_7369191014 分钟前
C++中的享元模式变体
开发语言·c++·算法
集芯微电科技有限公司20 分钟前
15V/2A同步开关型降压单节/双节锂电池充电管理IC支持输入适配器 DPM 功能
c语言·开发语言·stm32·单片机·嵌入式硬件·电脑
罗湖老棍子21 分钟前
【 例 1】石子合并(信息学奥赛一本通- P1569)
数据结构·算法·区间dp·区间动态规划·分割合并
小高Baby@44 分钟前
JSON、bind、form
数据结构·json
Tisfy1 小时前
LeetCode 3637.三段式数组 I:一次遍历(三种实现)
算法·leetcode·题解·模拟·数组·遍历·moines
菩提树下的凡夫1 小时前
Python 环境管理工具
开发语言·python
索荣荣1 小时前
JavaToken实战指南:从原理到应用
开发语言·python
zho_uzhou1 小时前
c++ imgui implot绘图使用示例 visual studio
开发语言·c++·visual studio
dyyx1111 小时前
C++中的过滤器模式
开发语言·c++·算法