Smallest Rectangle Enclosing Black Pixels
Description
An image is represented by a binary matrix with0
as a white pixel and1
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
For example, given the following image:
[
"0010",
"0110",
"0100"
]
and x =0
, y =2
,
Return6
.
Implementation
Link: http://lintcode.com/en/problem/smallest-rectangle-enclosing-black-pixels/
class Solution {
public:
/**
* @param image a binary matrix with '0' and '1'
* @param x, y the location of one of the black pixels
* @return an integer
*/
#if 0
int minArea(vector<vector<char>>& image, int x, int y) {
// Write your code here
int m = image.size();
if(m == 0) return 0;
int n = image[0].size();
if(n == 0) return 0;
int start = 0, end = x;
// first position of row
while (start < end) {
int mid = start + (end - start) / 2;
if (checkRow(image, mid)) {
end = mid;
} else {
start = mid + 1;
}
}
int up = start;
// last pos of row
start = x;
end = m - 1;
while (start < end) {
int mid = start + (end - start) / 2 + 1;
if (checkRow(image, mid)) {
start = mid;
} else {
end = mid - 1;
}
}
int bottom = start;
// first pos of col
start = 0;
end = y;
while (start < end) {
int mid = start + (end - start) / 2;
if (checkCol(image, mid)) {
end = mid;
} else {
start = mid + 1;
}
}
int left = start;
// last pos of col
start = y;
end = n - 1;
while (start < end) {
int mid = start + (end - start) / 2 + 1;
if (checkCol(image, mid)) {
start = mid;
} else {
end = mid - 1;
}
}
int right = start;
return (right - left + 1) * (bottom - up + 1);
}
bool checkRow(vector<vector<char>>& image, int row) {
for(int i = 0; i < image[row].size(); i++)
if(image[row][i] == '1') return true;
return false;
}
bool checkCol(vector<vector<char>>& image, int col) {
for (int i = 0; i < image.size(); i++)
if (image[i][col] == '1') return true;
return false;
}
#else
int minArea(vector<vector<char>>& image, int x, int y) {
int m = image.size();
if(m == 0) return 0;
int n = image[0].size();
if(n == 0) return 0;
int top = searchRow(image, 0, x, 0, n, true);
int bottom = searchRow(image, x + 1, m, 0, n, false);
int left = searchCol(image, 0, y, top, bottom, true);
int right = searchCol(image, y + 1, n, top, bottom, false);
// bottom and right are always + 1
return (right - left) * (bottom - top);
}
// opt: true - first position
// flase - last position
int searchRow(vector<vector<char>>& image,
int i, int j, int low, int high, bool opt) {
while (i != j) {
int mid = i + (j - i) / 2;
int k = low;
while (k < high && image[mid][k] == '0') ++k;
if (k < high == opt)
j = mid;
else
i = mid + 1;
}
return i;
}
int searchCol(vector<vector<char>>& image,
int i, int j, int low, int high, bool opt) {
while (i != j) {
int mid = i + (j - i) / 2;
int k = low;
while (k < high && image[k][mid] == '0') ++k;
if (k < high == opt)
j = mid;
else
i = mid + 1;
}
return i;
}
#endif
};