Smallest Rectangle Enclosing Black Pixels

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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]


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;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值