You are given a 2D binary image represented as a list of strings, where each string is a row and each character is either '0'
(white pixel) or '1'
(black pixel). You are also given the location (x, y)
of one of the black pixels.
Your task is to find the area of the smallest (axis-aligned) rectangle that encloses all black pixels ('1'
) in the image. The rectangle's sides must be parallel to the image axes.
x
and y
are guaranteed to be within the bounds of the image and point to a black pixel.
The naive approach is to scan the entire image and record the minimum and maximum row and column indices where a black pixel appears. This would let us compute the rectangle directly.
However, since the black region is connected and we’re given a starting black pixel, we can optimize by only searching the connected region using BFS or DFS. But, if the black area is large or scattered, scanning the whole image may be more straightforward.
To further optimize, we can use binary search to find the leftmost, rightmost, topmost, and bottommost black pixels, reducing the number of rows and columns we need to check.
The key insight is that the minimum rectangle is defined by the smallest and largest row and column indices containing a black pixel.
minRow
, maxRow
, minCol
, and maxCol
.
'1'
), update the boundary variables:
minRow
, update minRow
.maxRow
, update maxRow
.minCol
and maxCol
.(maxRow - minRow + 1) * (maxCol - minCol + 1)
.
For most cases, the simple scan is efficient and easy to understand.
Consider the following image:
image = [ "0010", "0110", "0100" ] x = 0, y = 2
The boundaries are:
The rectangle is from (0,1) to (2,2), so the area is (2-0+1) * (2-1+1) = 3 * 2 = 6
.
class Solution:
def minArea(self, image, x, y):
m, n = len(image), len(image[0])
minRow, maxRow = m, 0
minCol, maxCol = n, 0
for i in range(m):
for j in range(n):
if image[i][j] == '1':
minRow = min(minRow, i)
maxRow = max(maxRow, i)
minCol = min(minCol, j)
maxCol = max(maxCol, j)
return (maxRow - minRow + 1) * (maxCol - minCol + 1)
class Solution {
public:
int minArea(vector<string>& image, int x, int y) {
int m = image.size(), n = image[0].size();
int minRow = m, maxRow = 0, minCol = n, maxCol = 0;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (image[i][j] == '1') {
minRow = min(minRow, i);
maxRow = max(maxRow, i);
minCol = min(minCol, j);
maxCol = max(maxCol, j);
}
}
}
return (maxRow - minRow + 1) * (maxCol - minCol + 1);
}
};
class Solution {
public int minArea(char[][] image, int x, int y) {
int m = image.length, n = image[0].length;
int minRow = m, maxRow = 0, minCol = n, maxCol = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (image[i][j] == '1') {
minRow = Math.min(minRow, i);
maxRow = Math.max(maxRow, i);
minCol = Math.min(minCol, j);
maxCol = Math.max(maxCol, j);
}
}
}
return (maxRow - minRow + 1) * (maxCol - minCol + 1);
}
}
var minArea = function(image, x, y) {
let m = image.length, n = image[0].length;
let minRow = m, maxRow = 0, minCol = n, maxCol = 0;
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (image[i][j] === '1') {
minRow = Math.min(minRow, i);
maxRow = Math.max(maxRow, i);
minCol = Math.min(minCol, j);
maxCol = Math.max(maxCol, j);
}
}
}
return (maxRow - minRow + 1) * (maxCol - minCol + 1);
};
O(m * n)
, where m
is the number of rows and n
is the number of columns. Space complexity is O(1)
since we only use a few variables for boundaries.
O(k)
, where k
is the number of black pixels (since we only visit connected black pixels). Space complexity is O(k)
for the queue or stack.
O(log m * n)
time per direction, but since we need to check each row/column in the search, the overall complexity is still roughly O(m * n)
in the worst case.
The problem boils down to finding the minimum and maximum row and column indices of black pixels. By scanning the image and updating boundary variables, we can compute the area of the smallest rectangle that encloses all black pixels. This approach is simple, effective, and optimal for most practical input sizes. If the black region is much smaller than the image, BFS/DFS can further optimize the search. The elegance of the solution lies in its directness: just track the boundaries as you go!