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 ...
随机推荐
- Linux 高性能服务器编程——Linux服务器程序规范
问题聚焦: 除了网络通信外,服务器程序通常还必须考虑许多其他细节问题,这些细节问题涉及面逛且零碎,而且基本上是模板式的,所以称之为服务器程序规范. 工欲善其事,必先利其器,这篇主要来探 ...
- Linux动态频率调节系统CPUFreq之二:核心(core)架构与API
上一节中,我们大致地讲解了一下CPUFreq在用户空间的sysfs接口和它的几个重要的数据结构,同时也提到,CPUFreq子系统把一些公共的代码逻辑组织在一起,构成了CPUFreq的核心部分,这些公共 ...
- SpriteKit游戏Delve随机生成地牢地图一个Bug的修复
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Delve是一个很有意思的地牢探险类型的游戏,其中每一关的地图 ...
- JQuery 初探
放暑假了,终于有时间能学点前端的东西了.JQuery就是我第一个选择,锋利的JQuery.这本书真的很好.下面以一个ToggleButton形式的小例子开场吧. 引入JQuery库 在网页上引用JQu ...
- 剑指Offer——滴滴笔试题+知识点总结
剑指Offer--滴滴笔试题+知识点总结 情景回顾 时间:2016.9.18 15:00-17:00 地点:山东省网络环境智能计算技术重点实验室 事件:滴滴笔试 总体来说,滴滴笔试内容体量不算多, ...
- Django 表单校验 表单字段设置 自定义表单校验规则
今天看到了一篇非常好的博文,拿来和大家分享一下. 内容包括了: 用户注册时输入数据的校验 使用widget进行字段设置 实现自定义的校验规则 参考自下面的这篇文章
- 安卓高仿QQ头像截取升级版
观看此篇文章前,请先阅读上篇文章:高仿QQ头像截取: 本篇之所以为升级版,是在截取头像界面添加了与qq类似的阴影层(裁剪区域以外的部分),且看效果图: 为了适应大家不同需求,这次打了两个包,及上图 ...
- android打包引用第三方jar出现的错误
今天终于完成了近一个月的App开发工作,对程序进行混淆导出签名apk包时,却出现了如下的错误: Proguard returned with error code 1. See console Not ...
- Qt中事件分发源代码剖析
Qt中事件分发源代码剖析 Qt中事件传递顺序: 在一个应该程序中,会进入一个事件循环,接受系统产生的事件,并且进行分发,这些都是在exec中进行的. 下面举例说明: 1)首先看看下面一段示例代码: i ...
- Hessian源码分析--总体架构
Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议,因为采用的是二进制协 ...