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. Java进击C#——语法之IO操作

    本章简言 上一章我们对线程同步进行讲解.了解如何去处理可能发生的脏数据.而本章就要讲有关于C#在读取IO文件的时候,常常用到的操作类.这一章的内容会比较少.但是笔者还是总结出来让读者们有一个学习的方向 ...

  2. CAS FOR WINDOW ACTIVE DIRECTORY SSO单点登录

    一.CAS是什么? CAS(Central Authentication Service)是 Yale 大学发起的一个企业级的.开源的项目,旨在为 Web 应用系统提供一种可靠的单点登录解决方法(支持 ...

  3. 使用PublishSetting快速在Powershell中登录Azure

    使用Powershell 来管理Azure资源实在是一大快事. 在使用power script之前, 需要先连接到Azure上,其中使用导入PublishSetting文件是最方便的方法. 步骤: 1 ...

  4. 【.NET MF】.NET Micro Framework USB移植

    1.开发环境 windows 7  32位 MDK 4.54 .Net Micro Framework Porting Kit 4.2(RTM QFE2) .Net Micro Framework   ...

  5. Sublime Text 3 支持的热门插件推荐

    SublimeText是一款非常精巧的文本编辑器,适合编写代码.做笔记.写文章.它用户界面十分整洁,功能非同凡响,性能快得出奇.这些非常棒的特性 包括任意跳转(Goto Anything).多重选择( ...

  6. SQLite Expert Professional 3查看SQLite数据

    通常在android进行SQLite数据库的处理查看很不方便,于是自己下载了一个SQLite Expert Professional 3可视化工具用来进行查询数据,由于时间问题就不多说了,直接讲使用方 ...

  7. 你必须收藏的Github技巧

    一秒钟把Github项目变成前端网站 GitHub Pages大家可能都知道,常用的做法,是建立一个gh-pages的分支,通过setting里的设置的GitHub Pages模块可以自动创建该项目的 ...

  8. 用CSS3写一个立方体

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  9. 2D动画的制作

    通过css3的transform  transition可以实现平移,旋转,缩放,拉伸等效果 1.缩放 -webkit-transform: scale(1); -moz-transform: sca ...

  10. [译]为什么我要离开gulp和grunt转投npm脚本的怀抱

    原文链接:https://medium.freecodecamp.com/why-i-left-gulp-and-grunt-for-npm-scripts-3d6853dd22b8#.n7m1855 ...