- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章C++实现LeetCode(85.最大矩形)由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area. 。
Example
Input: [ ["1","0","1","0","0"], ["1","0","1","1","1"], ["1","1","1","1","1"], ["1","0","0","1","0"] ] Output: 6 。
此题是之前那道的 Largest Rectangle in Histogram 的扩展,这道题的二维矩阵每一层向上都可以看做一个直方图,输入矩阵有多少行,就可以形成多少个直方图,对每个直方图都调用 Largest Rectangle in Histogram 中的方法,就可以得到最大的矩形面积。那么这道题唯一要做的就是将每一层都当作直方图的底层,并向上构造整个直方图,由于题目限定了输入矩阵的字符只有 '0' 和 '1' 两种,所以处理起来也相对简单。方法是,对于每一个点,如果是 ‘0',则赋0,如果是 ‘1',就赋之前的 height 值加上1。具体参见代码如下:
解法一:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
class
Solution {
public
:
int
maximalRectangle(vector<vector<
char
> > &matrix) {
int
res = 0;
vector<
int
> height;
for
(
int
i = 0; i < matrix.size(); ++i) {
height.resize(matrix[i].size());
for
(
int
j = 0; j < matrix[i].size(); ++j) {
height[j] = matrix[i][j] ==
'0'
? 0 : (1 + height[j]);
}
res = max(res, largestRectangleArea(height));
}
return
res;
}
int
largestRectangleArea(vector<
int
>& height) {
int
res = 0;
stack<
int
> s;
height.push_back(0);
for
(
int
i = 0; i < height.size(); ++i) {
if
(s.empty() || height[s.top()] <= height[i]) s.push(i);
else
{
int
tmp = s.top(); s.pop();
res = max(res, height[tmp] * (s.empty() ? i : (i - s.top() - 1)));
--i;
}
}
return
res;
}
};
|
我们也可以在一个函数内完成,这样代码看起来更加简洁一些,注意这里的 height 初始化的大小为 n+1,为什么要多一个呢?这是因为我们只有在当前位置小于等于前一个位置的高度的时候,才会去计算矩形的面积,假如最后一个位置的高度是最高的,那么我们就没法去计算并更新结果 res 了,所以要在最后再加一个高度0,这样就一定可以计算前面的矩形面积了,这跟上面解法子函数中给 height 末尾加一个0是一样的效果,参见代码如下:
解法二:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class
Solution {
public
:
int
maximalRectangle(vector<vector<
char
>>& matrix) {
if
(matrix.empty() || matrix[0].empty())
return
0;
int
res = 0, m = matrix.size(), n = matrix[0].size();
vector<
int
> height(n + 1);
for
(
int
i = 0; i < m; ++i) {
stack<
int
> s;
for
(
int
j = 0; j < n + 1; ++j) {
if
(j < n) {
height[j] = matrix[i][j] ==
'1'
? height[j] + 1 : 0;
}
while
(!s.empty() && height[s.top()] >= height[j]) {
int
cur = s.top(); s.pop();
res = max(res, height[cur] * (s.empty() ? j : (j - s.top() - 1)));
}
s.push(j);
}
}
return
res;
}
};
|
下面这种方法的思路很巧妙,height 数组和上面一样,这里的 left 数组表示若当前位置是1且与其相连都是1的左边界的位置(若当前 height 是0,则当前 left 一定是0),right 数组表示若当前位置是1且与其相连都是1的右边界的位置再加1(加1是为了计算长度方便,直接减去左边界位置就是长度),初始化为n(若当前 height 是0,则当前 right 一定是n),那么对于任意一行的第j个位置,矩形为 (right[j] - left[j]) * height[j],我们举个例子来说明,比如给定矩阵为:
[ [ 1 , 1 , 0 , 0 , 1 ], [ 0 , 1 , 0 , 0 , 1 ], [ 0 , 0 , 1 , 1 , 1 ], [ 0 , 0 , 1 , 1 , 1 ], [ 0 , 0 , 0 , 0 , 1 ] ]
第0行:
h: 1 1 0 0 1 。
l: 0 0 0 0 4 。
r: 2 2 5 5 5 。
第1行:
h: 0 2 0 0 2 。
l: 0 1 0 0 4 。
r: 5 2 5 5 5 。
第2行:
h: 0 0 1 1 3 。
l: 0 0 2 2 4 。
r: 5 5 5 5 5 。
第3行:
h: 0 0 2 2 4 。
l: 0 0 2 2 4 。
r: 5 5 5 5 5 。
第4行:
h: 0 0 0 0 5 。
l: 0 0 0 0 4 。
r: 5 5 5 5 5 。
解法三:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
class
Solution {
public
:
int
maximalRectangle(vector<vector<
char
>>& matrix) {
if
(matrix.empty() || matrix[0].empty())
return
0;
int
res = 0, m = matrix.size(), n = matrix[0].size();
vector<
int
> height(n, 0), left(n, 0), right(n, n);
for
(
int
i = 0; i < m; ++i) {
int
cur_left = 0, cur_right = n;
for
(
int
j = 0; j < n; ++j) {
if
(matrix[i][j] ==
'1'
) {
++height[j];
left[j] = max(left[j], cur_left);
}
else
{
height[j] = 0;
left[j] = 0;
cur_left = j + 1;
}
}
for
(
int
j = n - 1; j >= 0; --j) {
if
(matrix[i][j] ==
'1'
) {
right[j] = min(right[j], cur_right);
}
else
{
right[j] = n;
cur_right = j;
}
res = max(res, (right[j] - left[j]) * height[j]);
}
}
return
res;
}
};
|
再来看一种解法,这里我们统计每一行的连续1的个数,使用一个数组 h_max, 其中 h_max[i][j] 表示第i行,第j个位置水平方向连续1的个数,若 matrix[i][j] 为0,那对应的 h_max[i][j] 也一定为0。统计的过程跟建立累加和数组很类似,唯一不同的是遇到0了要将 h_max 置0。这个统计好了之后,只需要再次遍历每个位置,首先每个位置的 h_max 值都先用来更新结果 res,因为高度为1也可以看作是矩形,然后我们向上方遍历,上方 (i, j-1) 位置也会有 h_max 值,但是用二者之间的较小值才能构成矩形,用新的矩形面积来更新结果 res,这样一直向上遍历,直到遇到0,或者是越界的时候停止,这样就可以找出所有的矩形了,参见代码如下:
解法四:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
class
Solution {
public
:
int
maximalRectangle(vector<vector<
char
>>& matrix) {
if
(matrix.empty() || matrix[0].empty())
return
0;
int
res = 0, m = matrix.size(), n = matrix[0].size();
vector<vector<
int
>> h_max(m, vector<
int
>(n));
for
(
int
i = 0; i < m; ++i) {
for
(
int
j = 0; j < n; ++j) {
if
(matrix[i][j] ==
'0'
)
continue
;
if
(j > 0) h_max[i][j] = h_max[i][j - 1] + 1;
else
h_max[i][0] = 1;
}
}
for
(
int
i = 0; i < m; ++i) {
for
(
int
j = 0; j < n; ++j) {
if
(h_max[i][j] == 0)
continue
;
int
mn = h_max[i][j];
res = max(res, mn);
for
(
int
k = i - 1; k >= 0 && h_max[k][j] != 0; --k) {
mn = min(mn, h_max[k][j]);
res = max(res, mn * (i - k + 1));
}
}
}
return
res;
}
};
|
到此这篇关于C++实现LeetCode(85.最大矩形)的文章就介绍到这了,更多相关C++实现最大矩形内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://www.cnblogs.com/grandyang/p/4322667.html 。
最后此篇关于C++实现LeetCode(85.最大矩形)的文章就讲到这里了,如果你想了解更多关于C++实现LeetCode(85.最大矩形)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
“用 Haskell 进行函数式思考”中的练习之一是使用融合定律使程序更加高效。我在尝试复制答案时遇到了一些麻烦。 部分计算要求您将 maximum (xs++ map (x+) xs) 转换为 ma
我正在尝试获得 R 中最大/最小的可表示数字。 输入“.Machine”后 我有: $double.xmin [1] 2.225074e-308 $double.xmax [1] 1.797693e+
有没有办法更改浏览器验证消息 请检查所附图片。 我目前正在使用 wooCommerce 目前它显示小于或等于 X 个数字,我想更改为请求超过 X 个项目的报价。 请多多指教 最佳答案 您需要使用oni
我正在尝试将解决方案从 Excel 求解器复制到 R 中,但不知道从哪里开始。 问题: 每小时选择 5 个选项(5 行),以最大化“分数”的总和,而无需在多个小时内选择同一组 2 次。 换句话说: 最
Haskell 中是否有这样的功能: max_of_type :: (Num a) => a 所以: max_of_type :: Int == 2 ^ 31 - 1 // for example,
我有这两个表示时间范围(秒)的输入字段,我需要这样设置,以便“from/min”字段不能高于“to/max”,反之亦然。 到目前为止我得到了这个: jQuery(document).ready(fun
我有一个看起来像这样的表: http://sqlfiddle.com/#!9/152d2/1/0 CREATE TABLE Table1 ( id int, value decimal(10,
我会尝试尽可能简单地解释它: 首先是一些带有虚拟数据的数据库结构。 结构 tb_spec_fk feature value ----------------- 1 1 1
我有两个表。 表 1: +---------+---------+ | Lead_ID | Deal_ID | +---------+---------+ | 2323 | null |
我的数据库中有一个字段可以包含数字,例如8.00 或范围编号,例如8.00 - 10.00。 如果您将每个数字作为单独的数字,我需要从表中获取 MIN() 和 MAX()。例如当范围为 8.00 -
max(float('nan'), 1) 计算结果为 nan max(1, float('nan')) 计算结果为 1 这是预期的行为吗? 感谢您的回答。 max 在 iterable 为空时引发异常
我想问一下如何在 CSS 中创建一个页脚栏,它具有最小宽度(比如 650 像素),并且会根据窗口大小进行拉伸(stretch),但仅限于某个点(比如 1024 像素)。 我的意思是当窗口大小为例如 1
我尝试调整表格列宽(下一个链接上的“作者”列 http://deploy.jtalks.org/jcommune/branches/1?lang=en)。我已将最小/最大属性添加到 .author-c
在 C# 中,是否有用于将最小值和最大值存储为 double 值的内置类? 此处列出的要点 http://msdn.microsoft.com/en-us/library/system.windows
问题: 每个任务队列是否可以每秒处理超过 500 个任务? 每个 GAE 应用是否可以每秒处理超过 50,000 个任务? 详细信息: Task queue quota文档说: Push Queue
我想知道是否允许最大或最小堆树具有重复值?我试图仅通过在线资源查找与此相关的信息,但一直没有成功。 最佳答案 是的,他们可以。您可以在“算法简介”(Charles E. Leiserson、Cliff
首先,我是 .NET 开发人员,喜欢 C# 中的 LINQ 和扩展方法。 但是当我编写脚本时,我需要相当于 Enumerable extension methods 的东西 任何人都可以给我任何建议/
这是一个检查最大 malloc 大小的简单程序: #include std::size_t maxDataSize = 2097152000; //2000mb void MallocTest(vo
我想找到我的数据的最小值和最大值。 我的数据文件: 1 2 4 5 -3 -13 112 -3 55 42 42 而我的脚本: {min=max=$1} {if ($1max) {max=$1}
我想查询我的Elastic-Search以获取仅具有正值的最低价格价格。我的价格也可以为零和-1;所以我不希望我的最小聚合返回0或-1。我知道我应该向查询(或过滤器)添加脚本,但是我不知道如何。我当前
我是一名优秀的程序员,十分优秀!