当前位置:网站首页>LeetCode·84.柱状图中最大的矩形·单调递增栈
LeetCode·84.柱状图中最大的矩形·单调递增栈
2022-08-04 15:51:00 【小迅想变强】
链接:https://leetcode.cn/problems/largest-rectangle-in-histogram/solution/by-xun-ge-v-626m/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目

示例
思路
解题思路
1. 暴力求解
**遇事不要慌,先暴力求解试试看,万一就过了呢,皆大欢喜**
当前本题过不了、、、、、、
没办法只能优化了,先说说暴力的思路,我们需要求最大面积,面积需要什么高 和 宽,那么我们直接枚举数组中所有的高和宽,然后搭配一下保存最大面积
- 枚举宽
我们固定每个数组元素为每个矩形的高,然后遍历数组,寻找每个矩形高能构成的最大面积,当左右两边第一次出现比当前高小的元素值,即为当前高能构成的最大值,每次保存最大值
- 枚举高
我们固定左右两边的长度即固定宽的长度,然后遍历数组,寻找当前长度中高最短的元素,即当前宽能构成的最大矩形,每次保存最大值
2. 单调栈
通过暴力解法,过不了,因为在枚举宽的同时需要寻找高,在枚举高的时候又要寻找宽,时间消耗非常大
那么可以利用递增栈优化暴力暴力求解的过程
- 当元素大于栈顶元素时,入栈
- 当元素小于栈顶元素时,维护栈的递增性,将小于当前元素的栈顶元素弹出,并计算面积
3. 单调栈+哨兵
在上面递增栈中,我们总是需要判断当前元素是否为最后元素或者为栈顶元素,很麻烦,那么可以在数组前后加上两个哨兵,充当坏点,在实际计算中不影响结果,但是简化我们的逻辑,正如我们高中或者初中学过的辅助线或者凑配法都是差不多的思路
具体实现看代码,注释超级详细
代码
1. 暴力求解
//枚举高
int largestRectangleArea(int* heights, int heightsSize){
int max = INT_MIN;//记录最大面积
for(int left = 0; left < heightsSize; left++)//左边宽
{
int minh = INT_MAX;
for(int right = left; right < heightsSize; right++)//右边宽
{
minh = fmin(minh, heights[right]);//取最小高
max = fmax(max, (right-left+1) * minh);//保存最大构成面积
}
}
return max;
}
作者:xun-ge-v
链接:https://leetcode.cn/problems/largest-rectangle-in-histogram/solution/by-xun-ge-v-626m/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。//枚举宽
int largestRectangleArea(int* heights, int heightsSize){
int max = -1;//记录最大面积
for(int mid = 0; mid < heightsSize; mid++)//
{
int h = heights[mid];//记录当前位置高
int left = mid, right = mid;
while(left-1 >= 0 && heights[left-1] >= h)//寻找最大宽度
{
left--;
}
while(right+1 < heightsSize && heights[right+1] >= h)
{
right++;
}
max = fmax(max, (right-left+1) * h);//保存最大面积
}
return max;
}
作者:xun-ge-v
链接:https://leetcode.cn/problems/largest-rectangle-in-histogram/solution/by-xun-ge-v-626m/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2. 单调栈
int largestRectangleArea(int* heights, int heightsSize)
{
int stack[heightsSize];//定义栈
int top = -1;
stack[++top] = 0;
int max = -1;
for(int i = 1; i < heightsSize; i++)//遍历数组
{
if(heights[i] >= heights[stack[top]])//入栈
{
stack[++top] = i;
}
else
{
while(top != -1 && heights[i] < heights[stack[top]])//出栈并计算面积,维护递增性,需要对小于的元素全部出栈
{
if(top-1 == -1)//最后一个栈顶元素,出栈计算面积需要包含一下前面和后面,因为矩形可以延伸,这里需要好好想一想
{
max = fmax(max, i * heights[stack[top]]);
}
else
{
max = fmax(max, (i - stack[top] + stack[top] - stack[top-1] - 1) * heights[stack[top]]);//栈中元素,计算面积与需要延伸,能延伸多长就延伸多长
}
--top;
}
stack[++top] = i;
}
}
while(top != -1)//数组元素全部遍历完了,单是栈还有元素,进行清空栈
{
if(top-1 == -1)
{
max = fmax(max, (heightsSize) * heights[stack[top]]);
}
else
{
max = fmax(max, (heightsSize - 1 - stack[top-1]) * heights[stack[top]]);
}
--top;
}
return max;
}
作者:xun-ge-v
链接:https://leetcode.cn/problems/largest-rectangle-in-histogram/solution/by-xun-ge-v-626m/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。3. 单调栈+哨兵
int largestRectangleArea(int* heights, int heightsSize)
{
int ans[heightsSize+2];//添加哨兵
ans[0] = 0;
ans[heightsSize+1] = 0;
for(int i = 0; i < heightsSize; i++)
{
ans[i+1] = heights[i];
}
int stack[heightsSize+2];//定义栈
int top = -1;
stack[++top] = 0;
int max = 0;
for(int i = 1; i < heightsSize+2; i++)
{
if(ans[i] >= ans[stack[top]])//入栈
{
stack[++top] = i;
}
else
{
while(ans[i] < ans[stack[top]])//出栈
{
max = fmax(max, (i - stack[top] + stack[top] - stack[top-1] - 1) * ans[stack[top]]);
--top;
}
stack[++top] = i;
}
}
return max;
}
作者:xun-ge-v
链接:https://leetcode.cn/problems/largest-rectangle-in-histogram/solution/by-xun-ge-v-626m/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。边栏推荐
- Crawler Xiaobai Notes (yesterday's supplement to pay attention to parsing data)
- DMS 有接口获取每个实例下的数据库列表吗
- An article to answer what is the product library of the DevOps platform
- 吴恩达机器学习[11]-机器学习性能评估、机器学习诊断
- Tinymce plugins [Tinymce 扩展插件集合]
- 全球电子产品需求放缓,三星手机越南工厂每周只需要干 3~4 天
- PHP 图片转PDF
- Jupyter常用操作总结(强烈建议收藏,持续更新实用操作)
- 解决dataset.mnist无法加载进去的情况
- Xi'an Zongheng Information × JNPF: Adapt to the characteristics of Chinese enterprises, fully integrate the cost management and control system
猜你喜欢

功率放大器的设计要点

"Research Report on the Development of Global Unicorn Enterprises in the First Half of 2022" released - DEMO WORLD World Innovation Summit ended successfully

##ansible自动化运维架构与简介

GPS satellite synchronization clock, NTP network synchronization clock, Beidou clock server (Jingzhun)

分支控制if-else

DevOps平台中的制品库是什么?有什么用处?

How to monitor code cyclomatic complexity by refactoring indicators

(2022杭电多校五)C - Slipper (dijkstra+虚拟结点)
![吴恩达机器学习[9]-神经网络学习](/img/07/0eeb3cd5f3ea7c2baeec1732ea8d9a.png)
吴恩达机器学习[9]-神经网络学习

NUS颜水成等发布首篇《深度长尾学习》综述
随机推荐
"Research Report on the Development of Global Unicorn Enterprises in the First Half of 2022" released - DEMO WORLD World Innovation Summit ended successfully
5 基本引用类型
Roslyn 在 msbuild 的 target 判断文件存在
云存储硬核技术内幕——(12) 皮洛士惨胜罗马军团
保证通信的机制有哪些
qt 复杂界面信号槽设计
一文详解什么是软件部署
招募 | 香港理工大学Georg Kranz 博士诚招博士
张乐:研发效能的黄金三角及需求与敏捷协作领域的实践|直播回顾
吴恩达机器学习[9]-神经网络学习
Jupyter常用操作总结(强烈建议收藏,持续更新实用操作)
How to monitor code cyclomatic complexity by refactoring indicators
C#命令行解析工具
An article to answer what is the product library of the DevOps platform
番茄插件番茄助手下载
JVM调优-GC基本原理和调优关键分析
把boot和APP一起烧录进MCU
Go 言 Go 语,一文看懂 Go 语言文件操作
实战:10 种实现延迟任务的方法,附代码!
分支控制if-else