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

作者推荐

【动态规划】【广度优先搜索】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.hqwc.cn/news/278637.html

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

相关文章

Kubernetes与Docker:容器编排的未来

在当今快速变化的技术领域&#xff0c;容器化技术已经成为现代应用开发的核心。Docker 提供了一种轻量、可移植、自包含的容器化解决方案&#xff0c;而 Kubernetes&#xff08;简称K8s&#xff09;则崛起为容器编排的事实标准。本文将深入研究 Kubernetes 和 Docker 的关系&am…

例如,用一个DatabaseRow类型表示一个数据库行(容器),用泛型Column<T>作为它的键

以下是一个简单的示例&#xff0c;演示如何使用泛型的Column<T>作为DatabaseRow的键&#xff0c;表示一个数据库行&#xff08;容器&#xff09;&#xff1a; // 列定义 class Column<T> {private String columnName;private T value;public Column(String column…

智能优化算法应用:基于静电放电算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于静电放电算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于静电放电算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.静电放电算法4.实验参数设定5.算法结果6.…

UniGUI 之UniDBGrid

目录 1]DataSource设置 2]显示MEMO类型里的文字 3]显示悬浮提示 4]显示当前记录及总记录数 5]读取所有记录&#xff0c;及分页 6]在前面加上序号列 7]不显示标题栏 8]列排序 9]编辑 和 更新 数据 10]获得某单元格里的内容 11]标题别名 12]将某列设置为CheckBox格式 13]列标题…

列表优先于数组

在Java中&#xff0c;列表&#xff08;List&#xff09;通常优于数组&#xff0c;因为列表提供了更灵活的操作和动态调整大小的能力。下面是一个例子&#xff0c;展示了为什么在某些情况下使用列表比数组更好&#xff1a; import java.util.ArrayList; import java.util.List;…

命令调用先构建hashTable

GPT 代码改 #include <stdio.h> #include <stdlib.h> #include <string.h>#define TABLE_SIZE 256struct Node {char *key;void *value;struct Node *next; };struct HashTable {struct Node *table[TABLE_SIZE]; };void initHashTable(struct HashTable *ha…

用CC三维建模建出的OSGB格式,用模方打不开,显示该路径包含OSGB瓦块数量0,是什么原因?

答&#xff1a;模方只识别tile命名的模型文件&#xff0c;此模型是不分块输出&#xff0c;要平面切块重新跑。 模方是一款针对实景三维模型的冗余碎片、水面残缺、道路不平、标牌破损、纹理拉伸模糊等共性问题研发的实景三维模型修复编辑软件。模方4.1新增自动单体化建模功能&…

字符设备驱动模块的编译

一. 简介 本文继上一篇文章的学习&#xff0c;上一篇文章学习了字符设备驱动框架的初步编写。文章地址如下&#xff1a; 字符设备驱动框架的编写-CSDN博客 本文对上一篇编写的驱动模块初步框架进行编译。 二. 字符设备驱动模块的编译 上一篇文章&#xff0c;编写了字符设备…

Kubernetes 的用法和解析 -- 2

一.集群常用指令 1.1 基础控制指令 # 查看对应资源: 状态 $ kubectl get <SOURCE_NAME> -n <NAMESPACE> -o wide [rootkube-master ~]# kubectl get pods -n kuboard -o wide# 查看对应资源: 事件信息 $ kubectl describe <SOURCE_NAME> <SOURCE_NAME_R…

Linux:符号和符号表

文章目录 什么是符号&#xff1f;什么是符号表&#xff1f;全局符号和本地符号1. 全局符号&#xff1a;symtab符号表 2. 本地符号&#xff1a; 符号在汇编阶段符号在链接阶段1.由模块 m 定义并能被其他模块引用的全局符号。2.由其他模块定义并被模块 m 引用的全局符号。3.只被模…

如何实现一个 RPC 框架?

如果让你自己设计 RPC 框架你会如何设计&#xff1f; 一般情况下&#xff0c; RPC 框架不仅要提供服务发现功能&#xff0c;还要提供负载均衡、容错等功能&#xff0c;这样的 RPC 框架才算真正合格的。 为了便于小伙伴们理解&#xff0c;我们先从一个最简单的 RPC 框架使用示意…

深入理解网络 I/O:单 Selector 多线程|单线程模型

&#x1f52d; 嗨&#xff0c;您好 &#x1f44b; 我是 vnjohn&#xff0c;在互联网企业担任 Java 开发&#xff0c;CSDN 优质创作者 &#x1f4d6; 推荐专栏&#xff1a;Spring、MySQL、Nacos、Java&#xff0c;后续其他专栏会持续优化更新迭代 &#x1f332;文章所在专栏&…