`

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.

[备注]
使用二分查找找出上下左右边界,其中上边界和左边界分别是包含了black区域最上面和最左边的pixel,而下边界和右边界分别是black区域下面和右边第一个white pixel,这样处理代码可以精简些,但我的思维方式却是僵硬地去找准确的四个边界。
另外,二分查找中左右边界调整的代码不容易理解,注释中给出了精简前的写法。

[ref]
https://leetcode.com/discuss/71898/1ms-java-binary-search-dfs-is-4ms

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;
    }
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics