LintCode 510: Maximal Rectangle
LintCode 510: Maximal Rectangle
题目描述
给你一个二维矩阵,权值为False和True,找到一个最大的矩形,使得里面的值全部为True,输出它的面积
Wed Nov 24 2016
思路
本题的思路比较多,可以用动态规划,也可以把本题看做是最长连续正数列的二维版本,还可以把本题看做多个求柱形图中得最大矩形问题。
如果用动态规划,记\(f(i, j, l)\)为以\((i, j)\)为左上角顶点,以\(l\)为列宽的矩形面积。指定\(i\),\(j\),通过变换\(l\),可以得到以\(i\),\(j\)为顶点的最大矩形面积。通过遍历\(i\),\(j\),可求出最终答案。此方法的时间复杂度为\(O(mn^2)\)。
对于连续最长正数列,只需从头到尾遍历一遍即可,用一个变量记录当前最大的长度,当遇到0时重置长度计数。应用到二维情况则是遍历左上角顶点和右下角顶点,时间复杂度是\(O(m^2n^2)\)。
对于在柱状图中求最大矩形,可以构造一个递增栈,使得求解的时间复杂度为\(O(n)\),应用到二维情况就是\(O(mn)\)。
在一维的问题中,给的数据是一个数列,第i个数表示第i个位置的柱形的高度。从数列的第一个数开始,依次将它们入栈,直到当前准备入栈的高度小于栈顶元素的高度为止。这样就维护了一个递增的序列。
此时就可以计算一次矩形的面积了。矩形的高度就是当前栈顶元素位置柱状图的高度,矩形的宽度就是从当前准备入栈却又没有入栈的元素的位置到栈顶的距离。同时栈顶元素出栈。
若栈顶出栈后当前准备入栈的元素高度还是小于当前栈顶元素的高度,则继续出栈,计算方法跟上面的一样,之所以可以直接用当前准备入栈又还没入栈的元素与栈顶元素的距离来表示矩形的宽度,是因为当前栈顶的元素是从栈顶到准备入栈元素之间所有柱状图中高度最矮的(比它高的都出栈了)。
如此循环,直到当前元素的高度比栈顶元素的高度高了,再正常入栈。
此方法中每个元素只有一次机会入栈,所以时间复杂度是\(O(n)\)。
应用到二维的问题中,其实就是把矩阵看作是多个柱状图的叠加。对于每一行,把那一行作为柱状图的横坐标,那一行以上1的个数就是该位置柱形的高度,那一行以下的部分忽略不计。在计算高度的时候,若某位置的元素是1,则该位置的高度等于上一行相同位置的高度加1,否则就直接是0。这样计算高度的算法的时间复杂度也是\(O(mn)\),总体的时间复杂度不变。
代码
// 从矩形中计算各个柱状图的高度
void getBarHeights(vector<vector<bool> > &matrix, vector<vector<int> > &heights)
{
int n = matrix.size();
int m = matrix[0].size();
vector<int> tmp;
for (vector<bool>::iterator iter = matrix[0].begin(); iter != matrix[0].end(); ++iter)
tmp.push_back(*iter);
heights.push_back(tmp);
for (int i = 1; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
if (matrix[i][j] == 0)
tmp[j] = 0;
else
tmp[j]++;
}
heights.push_back(tmp);
}
}
// 柱状图求最大矩形算法
int maxBarRec(vector<int>& height)
{
int max = 0;
int n = height.size();
stack<int> s;
for (int i = 0; i <= n; ++i)
{
int h = i == n ? 0 : height[i];
if (s.empty() || h > height[s.top()]) s.push(i);
else
{
while (!s.empty() && h <= height[s.top()])
{
int crr = s.top(); s.pop();
int area = height[crr] * (s.empty() ? i : i - s.top() - 1);
if (area > max) max = area;
}
--i;
}
}
return max;
}
// 主函数
int maximalRectangle(vector<vector<bool> > &matrix)
{
int m = matrix.size();
if (m <= 0) return 0;
int n = matrix[0].size();
int max = 0;
vector<vector<int> > heights;
getBarHeights(matrix, heights);
for (int i = m - 1; i >= 0; --i)
{
int tmax = maxBarRec(heights[i]);
if (tmax > max) max = tmax;
}
return max;
}
LintCode 510: Maximal Rectangle的更多相关文章
- [LintCode] Maximal Rectangle 最大矩形
Given a 2D boolean matrix filled with False and True, find the largest rectangle containing all True ...
- 85. Maximal Rectangle
85. Maximal Rectangle Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle c ...
- 求解最大矩形面积 — leetcode 85. Maximal Rectangle
之前切了道求解最大正方形的题,题解猛戳 这里.这道题 Maximal Rectangle 题意与之类似,但是解法完全不一样. 先来看这道题 Largest Rectangle in Histogram ...
- 【leetcode】Maximal Rectangle
Maximal Rectangle Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle conta ...
- 47. Largest Rectangle in Histogram && Maximal Rectangle
Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...
- leetcode Maximal Rectangle 单调栈
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4052721.html 题目链接:leetcode Maximal Rectangle 单调栈 ...
- leetcode面试准备: Maximal Rectangle
leetcode面试准备: Maximal Rectangle 1 题目 Given a 2D binary matrix filled with 0's and 1's, find the larg ...
- LeetCode之“动态规划”:Maximal Square && Largest Rectangle in Histogram && Maximal Rectangle
1. Maximal Square 题目链接 题目要求: Given a 2D binary matrix filled with 0's and 1's, find the largest squa ...
- 最大的矩形面积 Maximal Rectangle
2018-09-15 10:23:44 一.Largest Rectangle in Histogram 在求解最大的矩形面积之前,我们先讨论一条最大直方图面积的问题. 问题描述: 问题求解: 解法一 ...
随机推荐
- 小白用Android MVP-初体验(一)
写android以来,一直都是采用MVC的模式,所有的业务逻辑,网络请求等都放在了View中,即Activity或者Fragment中.看了一些mvp文章,很多跨度较大,也因为自己造诣不够,还不能跟上 ...
- J2EE体系
J2EE的概念 目前,Java 2平台有3个版本,它们是适用于小型设备和智能卡的Java 2平台Micro版(Java 2 Platform Micro Edition,J2ME).适用于桌面系统的J ...
- 【week10】规格说明书练习-吉林市1日游
假设我们全班同学及教师去吉林省吉林市1日游,请为这次活动给出规格说明书. 版本:1.0 编订:于淼 团队:2016级计算机技术全体同学 日期:2016/11/19 1.引言 1.1 编写目的 1.2 ...
- week1读构建之法-读书笔记
最开始听见杨老师说邹欣老师这个名字总觉得很熟悉,后来看见博客上老师的头像恍然大悟,原来机缘巧合已经在微博上关注邹老师许久,一直觉得邹老师是个很有意思的人,兴趣一定十分广泛,看了老师的书确实能感觉到邹老 ...
- selenium 概念及练习 !
1.selenium中如何判断元素是否存在? 2.selenium中hidden或者是display = none的元素是否可以定位到? 3.selenium中如何保证操作元素的成功率?也就是说如何保 ...
- docker+mesos+marathon
前言 (Core) [root@docker-slave ~]# uname -r 3.10.0-229.4.2.el7.x86_64 [root@docker-slave ~]# uname -m ...
- linux下sublime text 3安装到配置
1. Sublime Text 3的下载安装 到官方网站上http://www.sublimetext.com/3下载64位(系统位64位)的.deb安装包(http://c758482.r82.cf ...
- adb命令模拟按键事件KeyCode
例子: //这条命令相当于按了设备的Backkey键 adb shell input keyevent 4 //可以解锁屏幕 adb shell input keyevent 82 //在屏幕上做划 ...
- 内存测试——Android Studio中对应进程的Heap
通过Android Studio的Heap查看该程序的目前占用内存大小,多次进出界面,观察内存内存大小的变化.用Heap监测应用进程使用内存情况的步骤如下: 1. 启动Android Studio—& ...
- Visual Studio 中设置npm
VS2017自带的npm会去国外的镜像下载文件, 奇慢无比, 还是马云家淘宝的镜像适合国内用户. 淘宝npm镜像地址: https://registry.npm.taobao.org VS中使用淘宝 ...