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.
For example, given the following image:
[
"0010",
"0110",
"0100"
]
and x = 0, y = 2,
Return 6.
[备注]
使用二分查找找出上下左右边界,其中上边界和左边界分别是包含了black区域最上面和最左边的pixel,而下边界和右边界分别是black区域下面和右边第一个white pixel,这样处理代码可以精简些,但我的思维方式却是僵硬地去找准确的四个边界。
另外,二分查找中左右边界调整的代码不容易理解,注释中给出了精简前的写法。
[ref]
[url]https://leetcode.com/discuss/71898/1ms-java-binary-search-dfs-is-4ms[/url]
For example, given the following image:
[
"0010",
"0110",
"0100"
]
and x = 0, y = 2,
Return 6.
[备注]
使用二分查找找出上下左右边界,其中上边界和左边界分别是包含了black区域最上面和最左边的pixel,而下边界和右边界分别是black区域下面和右边第一个white pixel,这样处理代码可以精简些,但我的思维方式却是僵硬地去找准确的四个边界。
另外,二分查找中左右边界调整的代码不容易理解,注释中给出了精简前的写法。
[ref]
[url]https://leetcode.com/discuss/71898/1ms-java-binary-search-dfs-is-4ms[/url]
public class Solution {
// Solution 1: DFS, 4ms
public int minArea1(char[][] image, int x, int y) {
m = image.length;
n = image[0].length;
int[] edgePoints = {y, y, x, x};
recur(image, x, y, edgePoints);
int width = edgePoints[1] - edgePoints[0] + 1;
int height = edgePoints[3] - edgePoints[2] + 1;
return width * height;
}
private int m, n;
private int[] xDelta = {0, 0, 1, -1};
private int[] yDelta = {1, -1, 0, 0};
public void recur(char[][] image, int x, int y, int[] edgePoints) {
if (image[x][y] != '1')
return; // 0 or 2(visited)
edgePoints[0] = Math.min(edgePoints[0], y);
edgePoints[1] = Math.max(edgePoints[1], y);
edgePoints[2] = Math.min(edgePoints[2], x);
edgePoints[3] = Math.max(edgePoints[3], x);
image[x][y] = '2';
for (int i = 0; i < 4; i++) {
int x2 = x + xDelta[i];
int y2 = y + yDelta[i];
if (x2 >= 0 && x2 < m && y2 >= 0 && y2 < n)
recur(image, x2, y2, edgePoints);
}
}
// Solution 2: binary search, 1ms
public int minArea(char[][] image, int x, int y) {
int m = image.length, n = image[0].length;
int left = binarySearch(image, 0, y, 0, m, false, true); // search the first pos which belong to black
int right = binarySearch(image, y + 1, n, 0, m, false, false); // search the first pos which not belong to black
int top = binarySearch(image, 0, x, 0, n, true, true);
int bottom = binarySearch(image, x + 1, m, 0, n, true, false);
return (right - left) * (bottom - top);
}
public int binarySearch(char[][] image, int lower, int upper, int min, int max, boolean horizontal, boolean goLower) {
int mid;
while (lower < upper) {
mid = lower + (upper - lower) / 2;
boolean inside = false;
for (int i = min; i < max; i++) {
if ((horizontal ? image[mid][i] : image[i][mid]) == '1') {
inside = true;
break;
}
}
if (inside == goLower) {
upper = mid;
} else {
lower = mid + 1;
}
/*
if (inside) { // find black pixel, mid is in black region.
if (goLower) {
upper = mid;
} else {
lower = mid + 1;
}
} else {
if (goLower) {
lower = mid + 1;
} else {
upper = mid;
}
} */
}
return lower;
}
}

本文介绍了一种寻找二进制矩阵中黑色像素区域最小包围矩形的方法。通过深度优先搜索(DFS)和二分查找(Binary Search)两种算法实现,旨在找到包含所有黑色像素的最小矩形面积。
2301

被折叠的 条评论
为什么被折叠?



