An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black pixels are connected, i.e., there is only one black region. Pixels are connected horizontally and vertically. Given the location (x, y) of one of the black pixels, return the area of the smallest (axis-aligned) rectangle that encloses all black pixels.

Example:

Input:
[
"0010",
"0110",
"0100"
]
and x = 0, y = 2 Output: 6

这道题给我们一个二维矩阵,表示一个图片的数据,其中1代表黑像素,0代表白像素,现在让找出一个最小的矩阵可以包括所有的黑像素,还给了一个黑像素的坐标,先来看 Brute Force 的方法,这种方法的效率不高,遍历了整个数组,如果遇到了1,就更新矩形,参见代码如下:

解法一:

// Brute force
class Solution {
public:
int minArea(vector<vector<char>>& image, int x, int y) {
int left = y, right = y, up = x, down = x;
for (int i = ; i < image.size(); ++i) {
for (int j = ; j < image[i].size(); ++j) {
if (image[i][j] == '') {
left = min(left, j);
right = max(right, j);
up = min(up, i);
down = max(down, i);
}
}
}
return (right - left + ) * (down - up + );
}
};

下面这种解法是解法一的递归写法,本质上来说跟上面的解法没有啥区别,也没有任何的优化,所以仍然可以认为是暴力搜索法,参见代码如下:

解法二:

// DFS
class Solution {
public:
int minArea(vector<vector<char>>& image, int x, int y) {
int left = y, right = y, up = x, down = x;
dfs(image, x, y, left, right, up, down);
return (right - left + ) * (down - up + );
}
void dfs(vector<vector<char>> &image, int x, int y, int &left, int &right, int &up, int &down) {
if (x < || x >= image.size() || y < || y >= image[].size() || image[x][y] != '') return;
left = min(left, y);
right = max(right, y);
up = min(up, x);
down = max(down, x);
image[x][y] = '';
dfs(image, x + , y, left, right, up, down);
dfs(image, x - , y, left, right, up, down);
dfs(image, x, y + , left, right, up, down);
dfs(image, x, y - , left, right, up, down);
}
};

我们再来看一种优化了时间复杂度的解法,这是一种二分搜索法,以给定的一个黑像素 (x, y) 为中心,分别用二分法快速找到整个黑色区域的上下左右的临界点,然后直接算出面积。首先来看上边界怎么找,既然是以 (x, y) 为中心,而且上边界又是某个行数,那么其范围肯定在 [0, x] 之间,能成为上边界的条件是该行中至少有一个点是1,那么其列数的范围就在 [0, n] 之间,在进行二分搜索的时候,先根据i, j算出中间行 mid,然后列数从0开始遍历,直到找到为1的点,或者越界位置,然后判断列数是否越界,越界的话,说明当前行没有1,此时更新i为 mid+1,如果找到了1,那么更新j为 mid。找下边界也是同样的道理,但是跟上边界稍微又些不同的地方是,如果当前行找到了1,应该再往下找,那么i应该更新为 mid+1;如果没找到,就应该往上找,靠近 (x, y) 点;所以两种情况只是在二分法更新范围的地方正好相反,所以可以用一个 bool 型的变量 opt 来决定还如何更新行数。

下面来看如何确定左边界和右边界,其实跟确定上下边界大同小异。左边界是列数,若以 (x, y) 点为中心,那么其范围便是 [0, y],因为之前已经确定了上下边界 up 和 down 了,所以左边界点的行数范围就是 [up, down],同理,当通过i, j求出了中间列 mid 时,就要遍历该列,找到为1的点,所以此时是用 image[k][mid],而在找上下边界时,用的是 image[mid][k],还是顺序不一样,可以用另外一个 bool 型变量h来控制,h表示 horizontal,就是水平遍历的意思。这样通过两个 bool 型变量就可以用一个函数来涵盖四种情况的二分搜索,是不是很叼?下面更新i或j的时候参考上下边界的分析,应该不难理解,参见代码如下:

解法三:

// Binary Search
class Solution {
public:
int minArea(vector<vector<char>>& image, int x, int y) {
int m = image.size(), n = image[].size();
int up = binary_search(image, true, , x, , n, true);
int down = binary_search(image, true, x + , m, , n, false);
int left = binary_search(image, false, , y, up, down, true);
int right = binary_search(image, false, y + , n, up, down, false);
return (right - left) * (down - up);
}
int binary_search(vector<vector<char>> &image, bool h, int i, int j, int low, int high, bool opt) {
while (i < j) {
int k = low, mid = (i + j) / ;
while (k < high && (h ? image[mid][k] : image[k][mid]) == '') ++k;
if (k < high == opt) j = mid;
else i = mid + ;
}
return i;
}
};

参考资料:

https://leetcode.com/problems/smallest-rectangle-enclosing-black-pixels/

https://leetcode.com/problems/smallest-rectangle-enclosing-black-pixels/discuss/75128/1ms-Concise-Java-Binary-Search-(DFS-is-4ms)

https://leetcode.com/problems/smallest-rectangle-enclosing-black-pixels/discuss/75127/C%2B%2BJavaPython-Binary-Search-solution-with-explanation

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Smallest Rectangle Enclosing Black Pixels 包含黑像素的最小矩阵的更多相关文章

  1. LeetCode Smallest Rectangle Enclosing Black Pixels

    原题链接在这里:https://leetcode.com/problems/smallest-rectangle-enclosing-black-pixels/ 题目: An image is rep ...

  2. [Swift]LeetCode302. 包含黑色像素的最小矩形 $ Smallest Rectangle Enclosing Black Pixels

    An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black ...

  3. 【leetcode】302.Smallest Rectangle Enclosing Black Pixels

    原题 An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The bl ...

  4. 302. Smallest Rectangle Enclosing Black Pixels

    题目: An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The b ...

  5. Smallest Rectangle Enclosing Black Pixels

    An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black ...

  6. [Locked] Smallest Rectangle Enclosing Black Pixels

    An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black ...

  7. Smallest Rectangle Enclosing Black Pixels 解答

    Question An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. ...

  8. LC 302. Smallest Rectangle Enclosing Black Pixels【lock, hard】

    An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black ...

  9. leetcode Largest Rectangle in Histogram 单调栈

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4052343.html 题目链接 leetcode Largest Rectangle in ...

随机推荐

  1. Cesium原理篇:Property

    之前主要是Entity的一个大概流程,本文主要介绍Cesium的属性,比如defineProperties,Property(ConstantProperty,CallbackProperty,Con ...

  2. Hadoop入门学习笔记---part4

    紧接着<Hadoop入门学习笔记---part3>中的继续了解如何用java在程序中操作HDFS. 众所周知,对文件的操作无非是创建,查看,下载,删除.下面我们就开始应用java程序进行操 ...

  3. 【干货】用大白话聊聊JavaSE — ArrayList 深入剖析和Java基础知识详解(二)

    在上一节中,我们简单阐述了Java的一些基础知识,比如多态,接口的实现等. 然后,演示了ArrayList的几个基本方法. ArrayList是一个集合框架,它的底层其实就是一个数组,这一点,官方文档 ...

  4. 4.在MVC中使用仓储模式进行增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-using-the-repository-pattern-in-mvc/ 系列目录: ...

  5. 手把手教从零开始在GitHub上使用Hexo搭建博客教程(二)-Hexo参数设置

    前言 前文手把手教从零开始在GitHub上使用Hexo搭建博客教程(一)-附GitHub注册及配置介绍了github注册.git相关设置以及hexo基本操作. 本文主要介绍一下hexo的常用参数设置. ...

  6. 在DevExpress中使用CameraControl控件进行摄像头图像采集

    在我们以前的项目了,做摄像头的图片采集,我们一般还是需要做一个封装处理的,在较新版本的DevExpress控件里面,增加了一个CameraControl控件,可以直接调用摄像头显示的,因此也可以做头像 ...

  7. 【无私分享:ASP.NET CORE 项目实战(第十一章)】Asp.net Core 缓存 MemoryCache 和 Redis

    目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 经过 N 久反复的尝试,翻阅了网上无数的资料,GitHub上下载了十几个源码参考, Memory 和 Redis 终于写出一个 ...

  8. H-1B身份六年后的延期问题

    http://www.hooyou.com/cn_version/h-1b/extension.html H-1B首次获签的在美国居留时限是三年,三年期满后还可以申请延期再续三年,总计在美国的最长时限 ...

  9. 静态代理和利用反射形成的动态代理(JDK动态代理)

    代理模式 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 静态代理 1.新建 ...

  10. HTML5 数据集属性dataset

    有时候在HTML元素上绑定一些额外信息,特别是JS选取操作这些元素时特别有帮助.通常我们会使用getAttribute()和setAttribute()来读和写非标题属性的值.但为此付出的代价是文档将 ...