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.
一刷
题解:首先寻找left边界,该列是最远离y但是含有1的;
right边界,最靠近y不含1的。
同理找到top和bottom
public class Solution {
public int minArea(char[][] image, int x, int y) {
int m = image.length, n = image[0].length;
int left = searchCol(0, y, 0, m, true);
int right = searchCol(y+1, n, 0, m, false);
int top = searchRows(0, x, left, right, true);
int bottom = searchRows(x+1, m, left, right, false);
return (right - left)*(bottom - top);
}
private int searchCol(int i, int j, int top, int bottom, boolean opt){
while(i!=j){
int k = top, mid = (i+j)/2;
while(k<bottom && image[k][mid] == '0') k++;
if(k<bottom == opt) j = mid;
else i = mid+1;
}
return i;
}
private int searchRows(int i, int j, int left, int right, boolean opt) {
while (i != j) {
int k = left, mid = (i + j) / 2;
while (k < right && image[mid][k] == '0') ++k;
if (k < right == opt)
j = mid;
else
i = mid + 1;
}
return i;
}
}
二刷
binarySearch + 扫描
比如寻找left(左边界,就从上到下扫描,如果碰到了1, 就j往左移。
注意,如果寻找右边界,只能寻找第一个是0的地方。否则如果赋值left = mid, 那么mid永远得不到更新。这是利用binarySearch需要注意的地方
class Solution {
public int minArea(char[][] image, int x, int y) {
int m = image.length;
if(m == 0) return 0;
int n = image[0].length;
int left = searchLeft(image, 0, m, 0, y);//include the black
int right = searchRight(image, 0, m, y+1, n);
int top = searchTop(image, 0, x, 0, n);
int bottom = searchBottom(image, x+1, m, 0, n);
return (right-left)*(bottom-top);
}
private int searchTop(char[][] image,int i, int j, int left, int right){
while(i!=j){
int k = left, mid = (i+j)/2;
while(k<right && image[mid][k] == '0') k++;
if(k<right) j = mid;
else i = mid+1;//i include the i
}
return i;
}
private int searchBottom(char[][] image,int i, int j, int left, int right){
while(i!=j){
int k = left, mid = (i+j)/2;
while(k<right && image[mid][k] == '0') k++;
if(k<right) i = mid+1;
else j = mid;
}
return i;
}
private int searchLeft(char[][] image, int top, int bottom, int i, int j){
while(i!=j){
int k = top, mid = (i+j)/2;
while(k<bottom && image[k][mid] == '0') k++;//move down
if(k<bottom) j = mid;
else i = mid+1;
}
return i;
}
private int searchRight(char[][] image, int top, int bottom, int i, int j){
while(i!=j){
int k = top, mid = (i+j)/2;
while(k<bottom && image[k][mid] == '0') k++;
if(k<bottom) i = mid+1;
else j = mid;
}
return i;
}
}