【单调栈】【区间合并】LeetCode85:最大矩形

news2024/11/16 13:44:45

作者推荐

【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数

本文涉及的知识点

单调栈 区间合并

题目

给定一个仅包含 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’

分析

时间复杂度O(n2m)。枚举矩形的left和right,时间复杂度o(n^2)。指定left,right,计算连续1的数量大于等于width的行数,时间复杂度O(m)。

代码

核心代码

class Solution {
public:
	int maximalRectangle(vector<vector<char>>& matrix) {
		m_r = matrix.size();
		m_c = matrix.front().size();
		vector<vector<int>> vRightLen(m_r, vector<int>(m_c));
		for (int r = 0; r < m_r; r++)
		{
			for (int c = m_c - 1; c >= 0; c--)
			{
				if ('1' == matrix[r][c])
				{
					vRightLen[r][c] = 1 + ((m_c - 1 == c) ? 0 : vRightLen[r][c + 1]);
				}
			}
		}
		int iRet = 0;
		for (int left = 0; left < m_c; left++)
		{
			for (int right = left; right < m_c; right++)
			{
				const int width = right - left + 1;
				int height = 0;
				for (int r = 0; r < m_r; r++)
				{
					if (vRightLen[r][left] < width)
					{
						iRet = max(iRet, height * width);
						height = 0;
					}
					else
					{
						height++;
					}
				}
				iRet = max(iRet, height * width);
			}
		}
		return iRet;
	}
	int m_r, m_c;
};

测试用例

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]);
	}
}

template<class T>
void Assert(const T& t1, const T& t2)
{
	assert(t1 == t2);
}

int main()
{
	vector<vector<char>> matrix;
	int r;
	{
		Solution slu;		
		matrix = { {'1','0','1','0','0'},{'1','0','1','1','1'},{'1','1','1','1','1'},{'1','0','0','1','0'} };
		auto res = slu.maximalRectangle(matrix);
		Assert(6, res);
	}
	{
		Solution slu;
		matrix = { {'0'} };
		auto res = slu.maximalRectangle(matrix);
		Assert(0, res);
	}
	{
		Solution slu;
		matrix = { {'1'} };
		auto res = slu.maximalRectangle(matrix);
		Assert(1, res);
	}
	{
		Solution slu;
		matrix = { {'1','1'}};
		auto res = slu.maximalRectangle(matrix);
		Assert(2, res);
	}
	{
		Solution slu;
		matrix = { {'1'},{'1' } };
		auto res = slu.maximalRectangle(matrix);
		Assert(2, res);
	}
}

单调栈

枚举底部,本题就可以转化成柱形图的最大矩形

class Solution {
public:
	int maximalRectangle(vector<vector<char>>& matrix) {		
		m_c = matrix.front().size();
		vector<int> vHeights(m_c);
		int iRet = 0;
		for (int r = 0; r < matrix.size(); r++)
		{
			for (int c = m_c - 1; c >= 0; c--)
			{
				if ('1' == matrix[r][c])
				{
					vHeights[c] +=1 ;
				}
				else
				{
					vHeights[c] = 0 ;
				}
			}
			iRet = max(iRet, largestRectangleArea(vHeights));
		}
		return iRet;
	}
	int largestRectangleArea(vector<int>& heights) {
		m_c = heights.size();
		vector<pair<int, int>> vLeftHeightIndex;
		vector<int> vLeftFirstLess(m_c, -1), vRightFirstMoreEqual(m_c, m_c);//别忘记初始化
		for (int i = 0; i < m_c; i++)
		{
			while (vLeftHeightIndex.size() && (heights[i] <= vLeftHeightIndex.back().first))
			{
				vRightFirstMoreEqual[vLeftHeightIndex.back().second] = i;
				vLeftHeightIndex.pop_back();
			}
			if (vLeftHeightIndex.size())
			{
				vLeftFirstLess[i] = vLeftHeightIndex.back().second;
			}
			vLeftHeightIndex.emplace_back(heights[i], i);
		}
		int iRet = 0;
		for (int i = 0; i < m_c; i++)
		{
			iRet = max(iRet, heights[i] * (vRightFirstMoreEqual[i] - vLeftFirstLess[i] - 1));
		}
		return iRet;
	}
	int m_c;
};

2022年12月版代码

 class Solution {
 public:
	 int maximalRectangle(vector<vector<char>>& matrix) {
		 m_r = matrix.size();
		 m_c = matrix[0].size();
		 vector<vector<int>> leftNums;
		 leftNums.assign(m_r, vector<int>(m_c));
		 for (int r = 0; r < m_r; r++)
		 {
			 for (int c = 0; c < m_c; c++)
			 {
				 if ('0' == matrix[r][c])
				 {
					 leftNums[r][c] = 0;
				 }
				 else
				 {
					 leftNums[r][c] = 1 + ((c > 0) ? leftNums[r][c - 1] : 0);
				 }
			 }
		 }
		 		 
		 for (int c = 0; c < m_c; c++)
		 {
			 stack<pair<int, int>> sta;			 
			 for (int r = 0; r < m_r; r++)
			 {
				 int iMinR = r;
				 while (sta.size() && (sta.top().first > leftNums[r][c]))
				 {
					 PopStack(sta, iMinR, r);
				 }
				 if (sta.empty() || (sta.top().first < leftNums[r][c]))
				 {
					 sta.emplace(leftNums[r][c], iMinR);
				 }
			 }
			 
			 while (sta.size())
			 {
				 int iMinR = m_r;
				 PopStack(sta, iMinR, m_r);
			 }
		 }
		 return m_iMaxArea;
	 }
	 void PopStack(stack<pair<int, int>>& sta,int& iMinRow,int r )
	 {
		 int iWidth = sta.top().first;
		 iMinRow = sta.top().second;

		 sta.pop();
		 m_iMaxArea = max(m_iMaxArea, iWidth*(r - 1 - iMinRow + 1));
	 }
	 int m_r, m_c;
	 int m_iMaxArea = 0;
 };

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步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.coloradmin.cn/o/1314569.html

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

相关文章

遥感图像分割系统:融合空间金字塔池化(FocalModulation)改进YOLOv8

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 遥感图像分割是遥感技术领域中的一个重要研究方向&#xff0c;它的目标是将遥感图像中的不同地物或地物类别进行有效的分割和识别。随着遥感技术的不断发展和遥感…

iOS_给View的部分区域截图 snapshot for view

文章目录 1.将整个view截图返回image&#xff1a;2.截取view的部分区域&#xff0c;返回image&#xff1a;3.旧方法&#xff1a;4.Tips参考&#xff1a; 1.将整个view截图返回image&#xff1a; 这些 api 已被废弃&#xff0c;所以需要判断 iOS 版本 写两套代码&#xff1a; R…

【Java】5分钟读懂Java虚拟机架构

5分钟读懂Java虚拟机架构 Java虚拟机&#xff08;JVM&#xff09;架构JVM是如何工作的&#xff1f;1. 类加载器子系统2. 运行时数据区3. 执行引擎 相关资料 本文阐述了JVM的构成和组件。每个Java开发人员都知道字节码经由JRE&#xff08;Java运行时环境&#xff09;执行。但他们…

php入门、安装wampserver教程

php声称是全世界最好的语言&#xff0c;今天这篇文章就带大家入门学习php&#xff0c;php和python、javasript一样&#xff0c;是一种弱类型的脚本语言。 一、php开发环境搭建 作为初学者&#xff0c;学习php建议安装wampserver&#xff0c;wampserver是包含了apache、php和mys…

oracle 锁表解决办法

相关表介绍 V$LOCKED_OBJECT&#xff08;记录锁信息的表&#xff09;v$session&#xff08;记录会话信息的表&#xff09;v$sql&#xff08;记录 sql 执行的表&#xff09;dba_objects&#xff08;用来管理对象&#xff0c;表、库等等&#xff09; 查询锁表的 SID select b.…

网络入门---可变参数原理和日志模拟实现

目录标题 前言有关函数的几个性质介绍可变参数的用法介绍可变参数的一个注意事项可变参数的底层原理va_listva_endva_startva_arg_INTSIZEOF 可变参数的注意事项日志的实现日志的测试 前言 在上一篇文章中我们介绍了TCP协议有关的函数&#xff0c;大致就是服务端先通过listen函…

Android多国语言翻译 国际化

语言目录详细对应关系 Arabic, Egypt (ar-rEG) —————————–阿拉伯语&#xff0c;埃及 Arabic, Israel (ar-rIL) ——————————-阿拉伯语&#xff0c;以色列 Bulgarian, Bulgaria (bg-rBG) ———————保加利亚语&#xff0c;保加利亚 Catalan, Spain (ca-r…

函数栈帧的创建和销毁(编程底层原理)

本篇的内容格外的难写&#xff0c;里面包含了许多的专业术语名和汇编指令等晦涩难懂的东西&#xff0c;既不利于讲解&#xff0c;也不利于读者的理解。但我会尽力去讲述出里面的底层逻辑&#xff0c;帮助大家去理解里面的过程&#xff0c;理解编程的底层原理可以为我们后续更为…

YOLOv8 | 代码逐行解析(一) | 项目目录构造分析

一、本文介绍 Hello&#xff0c;大家好这次给大家带来的不是改进&#xff0c;是整个YOLOv8项目的分析&#xff0c;整个系列大概会更新7-10篇左右的文章&#xff0c;从项目的目录到每一个功能代码的都会进行详细的讲解&#xff0c;同时YOLOv8改进系列也突破了三十篇文章&#x…

助力工业产品质检,基于yolov5l集成CBAM注意力机制开发构建智能PCB电路板质检分析系统

AI助力工业质检智能生产制造已经有很多成功的实践应用了&#xff0c;在我们前面的系列博文中也有很多对应的实践&#xff0c;感兴趣的话可以自行移步阅读前面的博文即可&#xff0c;这里本文的核心目的就是想要基于改进的yolov5l来开发构建用于PCB电路板智能检测分析的模型&…

GZ015 机器人系统集成应用技术样题1-学生赛

2023年全国职业院校技能大赛 高职组“机器人系统集成应用技术”赛项 竞赛任务书&#xff08;学生赛&#xff09; 样题1 选手须知&#xff1a; 本任务书共 25页&#xff0c;如出现任务书缺页、字迹不清等问题&#xff0c;请及时向裁判示意&#xff0c;并进行任务书的更换。参赛队…

【Trino权威指南(第二版)】Trino的架构、trino架构组件、 trino连接器架构的细节、trino的查询执行模型

文章目录 一. Trino架构1. 架构概览2. 协调器3. 发现服务4. 工作节点 二. 基于连接器的架构三. 查询执行模型1. 解析—>查询计划2. 查询计划 —> 分布式查询计划3. 运行阶段3.1. 基础概念切片&#xff1a;并行单元page 与 exchange算子pipeline切片的driverOperator 3.2.…

C#上位机与欧姆龙PLC的通信01----项目背景

最近&#xff0c;【西门庆】作为项目经理负责一个70万的北京项目&#xff0c;需要在工控系统集成软件开发中和欧 姆龙PLC对接&#xff0c;考虑项目现场情况优先想到了采用FinsTCP通讯协议&#xff0c;接下来就是记录如何一步步实现这些通讯过程的&#xff0c;希望给电气工程师&…

Netty常见的设计模式

简介 设计模式在软件开发中起着至关重要的作用&#xff0c;它们是解决常见问题的经过验证的解决方案。而Netty作为一个优秀的网络应用程序框架&#xff0c;同样也采用了许多设计模式来提供高性能和可扩展性。在本文中&#xff0c;我们将探讨Netty中使用的一些关键设计模式&…

探索Linux服务器配置信息的命令

目录 前言1 uname2 lscpu3 free4 df5 lspci6 lsusb7 lshw结语 前言 Linux系统提供了许多命令&#xff0c;用于获取和查看服务器的软硬件配置信息。这些命令可以帮助管理员和用户了解系统的状态、资源使用情况以及硬件设备的相关信息。以下是一些常用的命令以及它们的作用、使用…

【单调栈]LeetCode84: 柱状图中最大的矩形

作者推荐 【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数 本文涉及的知识点 单调栈 题目 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形…

解决kernel32.dll丢失的修复方式,kernel32.dll预防错误的方法

kernel32.dll文件是电脑中的一个重要文件&#xff0c;如果电脑出现kernel32.dll丢失的错误提示&#xff0c;那么电脑中的一些程序将不能正常使用&#xff0c;那么出现这样的问题有什么解决办法呢&#xff1f;那么今天就和大家说说解决kernel32.dll丢失的修复方式。 一.kernel32…

elasticsearch|大数据|kibana的安装(https+密码)

前言&#xff1a; kibana是比较好安装的&#xff0c;但https密码就比较麻烦一些了&#xff0c;下面将就如何安装一个可在生产使用的kibana做一个简单的讲述 一&#xff0c; kibana版本和下载地址 这里我想还是强调一下&#xff0c;kibana的版本需要和elasticsearch的版本一…

数据库基础(实体,管理系统,日志,数据类型,键与约束)

基本概念 数据&#xff08;Data&#xff09;&#xff1a; 数据是描述事物的信息&#xff0c;可以是数字、文字、图像、音频等形式。数据库中存储的就是这些数据&#xff0c;这些数据可以是具体的实体&#xff08;如一个人的信息&#xff09;&#xff0c;也可以是抽象的概念&…

数据持久化与临时存储的对决:localStorage 与 sessionStorage(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…