您的位置:首页 > 其它

LeetCode 302. Smallest Rectangle Enclosing Black Pixels(最小面积矩形)

2016-04-19 07:06 543 查看
原题网址:https://leetcode.com/problems/smallest-rectangle-enclosing-black-pixels/

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
.
方法一:深度优先(递归)搜索,类似填色算法,时间复杂度O(nm)

public class Solution {
private int left, right, top, bottom;
private void scan(char[][] image, int x, int y) {
if (x < 0 || x >= image.length || y < 0 || y >= image[x].length || image[x][y] == '0') return;
left = Math.min(left, y);
right = Math.max(right, y);
top = Math.min(top, x);
bottom = Math.max(bottom, x);
image[x][y] = '0';
scan(image, x, y-1);
scan(image, x, y+1);
scan(image, x-1, y);
scan(image, x+1, y);
}
public int minArea(char[][] image, int x, int y) {
left = y;
right = y;
top = x;
bottom = x;
scan(image, x, y);
return (right-left+1)*(bottom-top+1);
}
}


方法二:二分法搜索,即分别对(x,y)的上下左右方向应用二分法查找,是二分法一个奇葩的应用。

public class Solution {
public int minArea(char[][] image, int x, int y) {
int left = y, right = y, top = x, bottom = x;
int low, high;
low = 0;
high = y;
while (low<=high) {
boolean black = false;
int m = (low+high)/2;
for(int i=0; i<image.length; i++) {
if (image[i][m]=='1') {
black = true;
break;
}
}
if (black) high = m - 1; else low = m + 1;
}
left = low;

low = y;
high = image[x].length-1;
while (low<=high) {
boolean black = false;
int m = (low+high)/2;
for(int i=0; i<image.length; i++) {
if (image[i][m]=='1') {
black = true;
break;
}
}
if (black) low = m + 1; else high = m - 1;
}
right = low;

low = 0;
high = x;
while (low<=high) {
boolean black = false;
int m = (low+high)/2;
for(int i=0; i<image[m].length; i++) {
if (image[m][i] == '1') {
black = true;
break;
}
}
if (black) high = m - 1; else low = m + 1;
}
top = low;

low = x;
high = image.length-1;
while (low<=high) {
boolean black = false;
int m = (low+high)/2;
for(int i=0; i<image[m].length; i++) {
if (image[m][i] == '1') {
black = true;
break;
}
}
if (black) low = m + 1; else high = m - 1;
}
bottom = low;

return (right-left)*(bottom-top);
}
}


简化:

public class Solution {
private boolean column(char[][] image, int col) {
for(int i=0; i<image.length; i++) {
if (image[i][col] == '1') return true;
}
return false;
}
private boolean row(char[][] image, int row) {
for(int i=0; i<image[row].length; i++) {
if (image[row][i] == '1') return true;
}
return false;
}
public int minArea(char[][] image, int x, int y) {

int left, right, top, bottom;
int i, j;

i=0; j=y;
while (i<=j) {
int m=(i+j)/2;
if (column(image, m)) j=m-1; else i=m+1;
}
left = i;

i=y; j=image[x].length-1;
while (i<=j) {
int m=(i+j)/2;
if (column(image, m)) i=m+1; else j=m-1;
}
right = j;

i=0; j=x;
while (i<=j) {
int m=(i+j)/2;
if (row(image, m)) j=m-1; else i=m+1;
}
top = i;

i=x; j=image.length-1;
while (i<=j) {
int m=(i+j)/2;
if (row(image, m)) i=m+1; else j=m-1;
}
bottom = j;

return (right-left+1) * (bottom-top+1);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: