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 square containing all 1's and return its area.
For example, given the following matrix:
Return 4.
在GeeksforGeeks有一个解决该问题的方法:
1) Construct a sum matrix S[R][C] for the given M[R][C].
a) Copy first row and first columns as it is from M[][] to S[][]
b) For other entries, use following expressions to construct S[][]
If M[i][j] is 1 then
S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1
Else /*If M[i][j] is 0*/
S[i][j] = 0
2) Find the maximum entry in S[R][C]
3) Using the value and coordinates of maximum entry in S[i], print
sub-matrix of M[][]
构造完‘和矩阵S’后,我们只需求得该矩阵的最大值就可以了。
为什么只需求得该最大值就可以了?而且相同的最大值可能有很多个。细想下式我们就会知道‘和矩阵S’中的每一个值表示的都是从其他节点(本结点左上)到本节点所能构成的最大正方形的边长长度。
S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1
具体的程序如下:
class Solution {
public:
int min(const int a, const int b, const int c)
{
int minVal = (a < b)?a:b;
return (minVal < c)?minVal:c;
}
int maximalSquare(vector<vector<char>>& matrix) {
int rows = matrix.size();
if(rows == )
return ;
int cols = matrix[].size();
if(cols == )
return ;
int maxEdge = ;
vector<vector<int> > sum(rows, vector<int>(cols, ));
for(int i = ; i < rows; i++)
{
if(matrix[i][] == '')
{
sum[i][] = ;
maxEdge = ;
}
}
for(int j = ; j < cols; j++)
{
if(matrix[][j] == '')
{
sum[][j] = ;
maxEdge = ;
}
}
for(int i = ; i < rows; i++)
for(int j = ; j < cols; j++)
{
if(matrix[i][j] == '')
sum[i][j] = ;
else
sum[i][j] = min(sum[i-][j-], sum[i-][j], sum[i][j-]) + ;
if(maxEdge < sum[i][j])
maxEdge = sum[i][j];
}
return maxEdge * maxEdge;
}
};
2. Largest Rectangle in Histogram
题目要求:
Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

The largest rectangle is shown in the shaded area, which has area = 10 unit.
For example,
Given height = [2,1,5,6,2,3],
return 10.
这道题目实际上跟动态规划没有什么关系,之所以将其放在这里是因为其跟下一道题关系很大。该题解法参考自一博文,程序如下:
class Solution {
public:
int largestRectangleArea(vector<int>& height) {
vector<int> s;
int sz = height.size();
height.resize(++sz);
int maxArea = ;
int i = ;
while(i < sz)
{
if(s.empty() || height[i] >= height[s.back()])
{
s.push_back(i);
i++;
}
else
{
int t = s.back();
s.pop_back();
maxArea = max(maxArea, height[t] * (s.empty() ? i : i - s.back() - ));
}
}
return maxArea;
}
};
该博文还照题目要求中的例子[2,1,5,6,2,3]解析了这个函数:
首先,如果栈是空的,那么索引i入栈。那么第一个i=0就进去吧。注意栈内保存的是索引,不是高度。然后i++。

然后继续,当i=1的时候,发现h[i]小于了栈内的元素,于是出栈。(由此可以想到,哦,看来stack里面只存放单调递增的索引)
这时候stack为空,所以面积的计算是h[t] * i.t是刚刚弹出的stack顶元素。也就是蓝色部分的面积。

继续。这时候stack为空了,继续入栈。注意到只要是连续递增的序列,我们都要keep pushing,直到我们遇到了i=4,h[i]=2小于了栈顶的元素。

这时候开始计算矩形面积。首先弹出栈顶元素,t=3。即下图绿色部分。

接下来注意到栈顶的(索引指向的)元素还是大于当前i指向的元素,于是出栈,并继续计算面积,桃红色部分。

最后,栈顶的(索引指向的)元素大于了当前i指向的元素,循环继续,入栈并推动i前进。直到我们再次遇到下降的元素,也就是我们最后人为添加的dummy元素0.

同理,我们计算栈内的面积。由于当前i是最小元素,所以所有的栈内元素都要被弹出并参与面积计算。

注意我们在计算面积的时候已经更新过了maxArea。
总结下,我们可以看到,stack中总是保持递增的元素的索引,然后当遇到较小的元素后,依次出栈并计算栈中bar能围成的面积,直到栈中元素小于当前元素。
3. Maximal Rectangle
题目要求:
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
这道题的解决方法可以借鉴上题求直方图最大面积的方法,即我们把每一列当作直方图的每一列,输入则是每一列连续的‘1’的个数,具体程序如下:
class Solution {
public:
int largestRectangleArea(vector<int>& height) {
vector<int> s;
int sz = height.size();
height.resize(++sz);
int maxArea = ;
int i = ;
while(i < sz)
{
if(s.empty() || height[i] >= height[s.back()])
{
s.push_back(i);
i++;
}
else
{
int t = s.back();
s.pop_back();
maxArea = max(maxArea, height[t] * (s.empty() ? i : i - s.back() - ));
}
}
return maxArea;
}
int maximalRectangle(vector<vector<char>>& matrix) {
int rows = matrix.size();
if(rows == )
return ;
int cols = matrix[].size();
vector<vector<int> > height(rows, vector<int>(cols, ));
for(int i = ; i < rows; i++)
for(int j = ; j < cols; j++)
{
if(matrix[i][j] != '')
height[i][j] = (i == ) ? : height[i-][j] + ;
}
int maxArea = ;
for(int i = ; i < rows; i++)
maxArea = max(maxArea, largestRectangleArea(height[i]));
return maxArea;
}
};
LeetCode之“动态规划”:Maximal Square && Largest Rectangle in Histogram && Maximal Rectangle的更多相关文章
- 47. Largest Rectangle in Histogram && Maximal Rectangle
Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...
- leetcode@ [84/85] Largest Rectangle in Histogram & Maximal Rectangle
https://leetcode.com/problems/largest-rectangle-in-histogram/ https://leetcode.com/problems/maximal- ...
- 【动态规划】leetcode - Maximal Square
称号: Maximal Square Given a 2D binary matrix filled with 0's and 1's, find the largest square contain ...
- [LeetCode] Largest Rectangle in Histogram O(n) 解法详析, Maximal Rectangle
Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar height ...
- LeetCode 84--柱状图中最大的矩形( Largest Rectangle in Histogram) 85--最大矩形(Maximal Rectangle)
84题和85五题 基本是一样的,先说84题 84--柱状图中最大的矩形( Largest Rectangle in Histogram) 思路很简单,通过循环,分别判断第 i 个柱子能够延展的长度le ...
- [LeetCode] Maximal Square 最大正方形
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ret ...
- [LeetCode] Largest Rectangle in Histogram 直方图中最大的矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- [LeetCode] 84. Largest Rectangle in Histogram 直方图中最大的矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- [LeetCode] 221. Maximal Square 最大正方形
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ret ...
随机推荐
- Hibernate之综合问题
n + 1问题 query.iterate()方式返回迭代查询会开始发出一条语句:查询所有记录ID语句 Hibernate: select student0_.id ascol_0_0_from t_ ...
- SQLite Where 子句(http://www.w3cschool.cc/sqlite/sqlite-where-clause.html)
SQLite Where 子句 SQLite的 WHERE 子句用于指定从一个表或多个表中获取数据的条件. 如果满足给定的条件,即为真(true)时,则从表中返回特定的值.您可以使用 WHERE 子句 ...
- BeanUtils Exception 之 FastHashMap
这里仅仅是为了记录一件十分奇怪的事情,在使用BeanUtils的过程中,所有的依赖包都添加了, common logging common collections ··· 在为boolean 这种基本 ...
- Hadoop与分布式数据处理 Spark VS Hadoop有哪些异同点?
Spark是一个开源的通用并行分布式计算框架,由加州大学伯克利分校的AMP实验室开发,支持内存计算.多迭代批量处理.即席查询.流处理和图计算等多种范式.Spark内存计算框架适合各种迭代算法和交互式数 ...
- Effective C++ ——让自己习惯C++
条款一:视C++为一个语言联邦 为了理解C++,你必须认识其主要的次语言.幸运的是总共只有四个: C:C++是由C语言继承而来的,必然对C有很好的兼容性,这一部分主要包括C中的一些语言,库函数等.但当 ...
- Android传感器
Android传感器 开发传感器应用 1. 获取传感器管理者对象 // 获取传感器管理者对象 SensorManager mSensorManager = (SensorManager) getSys ...
- Hadoop:Hadoop单机伪分布式的安装和配置
http://blog.csdn.net/pipisorry/article/details/51623195 因为lz的linux系统已经安装好了很多开发环境,可能下面的步骤有遗漏. 之前是在doc ...
- linux shell bash使用管道|和read结合时问题解决
最近在将ksh转成bash运行的时候出现了问题.代码如下: echo $1 | sed 's/\..*$/''/' | read FILE_NAME 当使用ksh执行的时候没有问题,FILE_NAME ...
- 【ShaderToy】基础篇之谈谈点、线的绘制
写在前面 写前面一篇的时候,发现还是不够基础.因此打算增加几篇基础篇,从点线面开始,希望可以更好理解. 其实用Pixel Shader的过程很像在纸上绘画的过程.屏幕上的每一个像素对应了纸上的一个方格 ...
- mac OS下在控制台中发送外部邮件
1 首先安装mailx: sudo port install mailx 2 然后设置别名 : alias mailx=/opt/local/bin/mailx alias mail=/opt/loc ...