【单调栈】【网格】【柱图面积】85. 最大矩形

作者推荐

视频算法专题

本文涉及的基础知识点

单调栈分类、封装和总结
网格

LeetCode85. 最大矩形

给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例 1:
在这里插入图片描述

输入:matrix = [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]
输出:6
解释:最大矩形如上图所示。
示例 2:

输入:matrix = [[“0”]]
输出:0
示例 3:

输入:matrix = [[“1”]]
输出:1

提示:

rows == matrix.length
cols == matrix[0].length
1 <= row, cols <= 200
matrix[i][j] 为 ‘0’ 或 ‘1’

单调栈

求以各行为底的柱状图的最大矩形面积。
vHeight 是柱形图的高度

for (int c = 0; c < m_c; c++)
{
if ((‘0’ == matrix[r][c]))
{
vHeight[c] = 0;
}
else
{
vHeight[c]++;
}
}

MaxArea 求柱形图最大矩形面积。
枚举以 vHeight[i]为高度的矩形,此矩形的左边界为: 从右向左,第一个小于等于vHeight[i]的柱子。
此矩形的右边界为,从左到右,第一个小于vHeight[i]的柱子。
左开右开空间。

代码

核心代码

template
class CRangFeture
{
public:
CRangFeture(const vector& nums) :m_nums(nums), Que(m_queIndexs)
{

}
int AddIndex(int cur)
{while (m_queIndexs.size() && (m_pr(m_nums[cur], m_nums[m_queIndexs.back()]))){m_queIndexs.pop_back();}int iRet = (m_queIndexs.size()) ? m_queIndexs.back() : -1;m_queIndexs.push_back(cur);return iRet;
}
void RemoveHeadIndex(int cur)
{if (m_queIndexs.size() && (cur == m_queIndexs.front())){m_queIndexs.pop_front();}
}
const deque<int>& Que;

protected:
int FrontValue()
{
return m_nums[m_queIndexs.front()];
}
deque m_queIndexs;
const vector& m_nums;
_PrCurValueCmpTailValue m_pr;
};

class Solution {
public:
int maximalRectangle(vector<vector>& matrix) {
m_c = matrix[0].size();
vector vHeight(m_c);
int iRet = 0;
for (int r = 0; r < matrix.size(); r++)
{
for (int c = 0; c < m_c; c++)
{
if ((‘0’ == matrix[r][c]))
{
vHeight[c] = 0;
}
else
{
vHeight[c]++;
}
}
iRet = max(iRet, MaxArea(vHeight));
}
return iRet;
}
int MaxArea(const vector& vHeight)
{
vector vLeft(m_c,-1);
CRangFeture<std::less> rLeft(vHeight);
for (int i = 0; i < m_c; i++)
{
vLeft[i] = rLeft.AddIndex(i);
}
int iRet = 0;
vector revNums(vHeight.rbegin(), vHeight.rend());
CRangFeture<std::less_equal> rRight(revNums);
for (int i = 0; i < m_c; i++)
{
const int iRight = m_c-1- rRight.AddIndex(i);
const int leftIndex = m_c - 1 - i;
const int iArea = (iRight - vLeft[leftIndex] - 1) * vHeight[leftIndex];
iRet = max(iRet, iArea);
}
return iRet;
}
int m_c;
};

测试用例

template<class T, class T2>
void Assert(const T& t1, const T2& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}}int main()
{vector<vector<char>> matrix;{Solution sln;matrix = { {'1','0','1','0','0'},{'1','0','1','1','1'},{'1','1','1','1','1'},{'1','0','0','1','0'} };auto res = sln.maximalRectangle(matrix);Assert(6, res);}{Solution sln;matrix = { {'0'} };auto res = sln.maximalRectangle(matrix);Assert(0, res);}{Solution sln;matrix = { {'1'} };auto res = sln.maximalRectangle(matrix);Assert(1, res);}
}

优化单调栈

当cur被淘汰pre时,说明cur < pre,且cur 是第一个小于pre的,否则pre会第一个cur淘汰。
故:vRight[pre] =cur

template<class _PrCurValueCmpTailValue>
class CRangFeture
{
public:CRangFeture(const vector<int>& nums) :m_nums(nums), Que(m_queIndexs){}int AddIndex(int cur){while (m_queIndexs.size() && (m_pr(m_nums[cur], m_nums[m_queIndexs.back()]))){OnPop(cur, m_queIndexs.back());m_queIndexs.pop_back();}int iRet = (m_queIndexs.size()) ? m_queIndexs.back() : -1;m_queIndexs.push_back(cur);return iRet;}void RemoveHeadIndex(int cur){if (m_queIndexs.size() && (cur == m_queIndexs.front())){m_queIndexs.pop_front();}}const deque<int>& Que;
protected:virtual void OnPop(int cur, int pre) {};int FrontValue(){return m_nums[m_queIndexs.front()];}deque<int> m_queIndexs;const vector<int>& m_nums;_PrCurValueCmpTailValue m_pr;
};template<class _PrCurValueCmpTailValue>
class CLeftRight : public CRangFeture<_PrCurValueCmpTailValue>
{
public:CLeftRight(const vector<int>& nums) :CRangFeture<_PrCurValueCmpTailValue>(nums){m_vLeft.assign(nums.size(), -1);m_vRight.assign(nums.size(), nums.size());}void Init(){for (int i = 0; i < this->m_nums.size(); i++){m_vLeft[i] = this->AddIndex(i);}}vector<int> m_vLeft, m_vRight;
protected:void OnPop(int cur, int pre){m_vRight[pre] = cur;}
};class Solution {
public:int maximalRectangle(vector<vector<char>>& matrix) {m_c = matrix[0].size();vector<int> vHeight(m_c);int iRet = 0;for (int r = 0; r < matrix.size(); r++){for (int c = 0; c < m_c; c++){if (('0' == matrix[r][c])){vHeight[c] = 0;}else{vHeight[c]++;}}iRet = max(iRet, MaxArea(vHeight));}return iRet;}int MaxArea(const vector<int>& vHeight){		CLeftRight<std::less<int>> lr(vHeight);	lr.Init();int iRet = 0;		for (int i = 0; i < m_c; i++){const int iArea = (lr.m_vRight[i] - lr.m_vLeft[i] - 1) * vHeight[i];iRet = max(iRet, iArea);}return iRet;}int m_c;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【氮化镓】GaN器件中关态应力诱导的损伤定位

概括总结&#xff1a; 这项研究通过低频1/f噪声测量方法&#xff0c;探究了在关态&#xff08;OFF-state&#xff09;应力作用下&#xff0c;AlGaN/GaN高电子迁移率晶体管&#xff08;HEMTs&#xff09;中由应力引起的损伤的定位。研究中结合了电致发光&#xff08;EL&#xf…

基于Hive的天气情况大数据分析系统(通过hive进行大数据分析将分析的数据通过sqoop导入到mysql,通过Django基于mysql的数据做可视化)

基于Hive的天气情况大数据分析系统&#xff08;通过hive进行大数据分析将分析的数据通过sqoop导入到mysql&#xff0c;通过Django基于mysql的数据做可视化&#xff09; Hive介绍&#xff1a; Hive是建立在Hadoop之上的数据仓库基础架构&#xff0c;它提供了类似于SQL的语言&…

ClamAV:Linux服务器杀毒扫描工具

Clam AntiVirus&#xff08;ClamAV&#xff09;是免费而且开放源代码的防毒软件&#xff0c;软件与病毒码的更新皆由社群免费发布。ClamAV在命令行下运行&#xff0c;它不将杀毒作为主要功能&#xff0c;默认只能查出系统内的病毒&#xff0c;但是无法清除。需要用户自行对病毒…

实验2:CLI的使用与IOS基本命令

1、实验目的 通过本实验可以掌握&#xff1a; CLI的各种工作模式个CLI各种编辑命令“?” 和【Tab】键使用方法IOS基本命令网络设备访问限制查看设备的相关信息 2、实验拓扑 CLI的使用与IOS基本命令使用拓扑如下图所示。 3、实验步骤 &#xff08;1&#xff09;CLI模式的切…

Leetcoder Day43| 单调栈2

503.下一个更大元素II 给定一个循环数组&#xff08;最后一个元素的下一个元素是数组的第一个元素&#xff09;&#xff0c;输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序&#xff0c;这个数字之后的第一个比它更大的数&#xff0c;这意味着你应该…

【chemistry 5】糖化学、脂化学和糖代谢

&#x1f31e;欢迎来到生物化学的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; &#x1f4c6;首发时间&#xff1a;&#x1f339;2024年3月29日&…

Spring Cloud+Spring Alibaba笔记

Spring CloudSpring Alibaba 文章目录 Spring CloudSpring AlibabaNacos服务发现配置中心 OpenFeign超时机制开启httpclient5重试机制开启日志 SeataSentinel流量控制熔断降级热点控制规则持久化集成 OpenFeign集成 Gateway MicrometerZipKinGateway路由断言过滤器 Nacos 服务…

上海斯歌高级顾问付梁钊,受邀出席“2024企业数字化转型高峰论坛”并进行主题演讲

本文转载自公众号CIO时代网 今年政府工作报告提出&#xff0c;发展新质生产力&#xff0c;深入推进数字经济创新发展。以科技创新推动产业创新&#xff0c;加快推进新型工业化&#xff0c;提高全要素生产率&#xff0c;不断塑造发展新动能新优势&#xff0c;促进社会生产力实现…

HarmonyOS 应用开发之任务(Mission)管理场景介绍

任务&#xff08;Mission&#xff09;管理相关的基本概念如下&#xff1a; AbilityRecord&#xff1a;系统服务侧管理一个UIAbility实例的最小单元&#xff0c;对应一个应用侧的UIAbility组件实例。系统服务侧管理UIAbility实例数量上限为512个。MissionRecord&#xff1a;任务…

Postman中参数填写方式!

Postman中参数填写和请求方法有关&#xff0c;一般接口用例请求方法GET与POST常用&#xff0c;所以主要是这两种请求方法请求参数填写 一、GET请求方法参数填写 1、直接在URL中填写请求参数,如直接在URL中填写&#xff1a; http://www.example.com:8089/userapi?unamelisi&…

机器学习之聚类算法、随机森林

文章目录 随机森林决策树基础特征值问题&#xff1f; 聚类算法 随机森林 决策树 基础 概念&#xff1a;从根节点一步步走到叶子节点&#xff08;决策&#xff09;&#xff1b; 组成&#xff1a;根节点第一个选择的节点&#xff1b;叶子节点最终的决策结果&#xff1b;非叶子…

基于CNN-RNN的动态手势识别系统实现与解析

一、环境配置 为了成功实现基于CNN-RNN的动态手势识别系统&#xff0c;你需要确保你的开发环境已经安装了以下必要的库和工具&#xff1a; Python&#xff1a;推荐使用Python 3.x版本&#xff0c;作为主要的编程语言。TensorFlow&#xff1a;深度学习框架&#xff0c;用于构建…