Smallest Rectangle Enclosing Black Pixels

Description:

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.

問題描述:

圖像中的黑色像素用1表示,白色像素用0表示,圖像中所有的黑色像素是連通的,求最小的矩陣區域能夠把圖像中所有黑色像素連成一片。給了初始黑色像素點(X,Y)。

解法一:

思路:

題目想要我們做的事情是想象成兩行,兩列,往中間縮緊,直到含有一個黑的爲止。。
即找到四個邊界,以左邊界爲例說明,找到第一個有黑色像素的一列。。其餘四個邊界同理可得,找到最後一個有黑色像素的一列,找到第一個有黑色像素的一行,找到最後一個有黑色像素的一行。。
問題轉換爲找到第一個、最後一個、任意一個滿足x條件的某個東西。。。所以用四個二分,並且寫有黑色元素(或者全爲白色元素的輔助函數)

Code:

代碼中的if 比較囉嗦,爲了便於讀者理解,先不改了。。。

public class Solution {
    /**
     * @param image a binary matrix with '0' and '1'
     * @param x, y the location of one of the black pixels
     * @return an integer
     */
    public int minArea(char[][] image, int x, int y) {
        // Write your code here
        if (image == null || image.length == 0 || image[0].length == 0){
            return -1;
        }
        int row = image.length;
        int col = image[0].length;

        int left = findLeft(image, 0, y);
        int right = findRight(image, y, col - 1);
        int top = findTop(image, 0, x);
        int bottom = findBottom(image, x, row - 1);

        return (right - left + 1) * (bottom - top + 1);
    }
    private int findLeft(char[][] image, int start, int end){
        while (start + 1 < end){
            int mid = start + (end - start) / 2;
            if (isEmptyCol(image, mid) == true){
                start = mid;
            } else {
                end = mid;
            }
        }
        if (isEmptyCol(image, start) == false){
            return start;
        } else {
            return end;
        }
    }
    private int findRight(char[][] image, int start, int end){
        while (start + 1 < end){
            int mid = start + (end - start) / 2;
            if (isEmptyCol(image, mid) == true){
                end = mid;
            } else {
                start = mid;
            }
        }
        if (isEmptyCol(image, end) == false){
            return end;
        } else {
            return start;
        }
    }
    private int findTop(char[][] image, int start, int end){
        while (start + 1 < end){
            int mid = start + (end - start) / 2;
            if (isEmptyRow(image, mid) == true){
                start = mid;
            } else {
                end = mid;
            }
        }
        if (isEmptyRow(image, start) == false){
            return start;
        } else {
            return end;
        }
    }
    private int findBottom(char[][] image, int start , int end){
        while (start + 1 < end){
            int mid = start + (end - start) / 2;
            if (isEmptyRow(image, mid) == true){
                end = mid;
            } else {
                start = mid;
            }
        }
        if (isEmptyRow(image, end) == false){
            return end;
        } else {
            return start;
        }
    }
    private boolean isEmptyCol(char[][] image, int col){
        for (int i = 0; i < image.length; i++){
            if (image[i][col] == '1'){
                return false;
            }
        }
        return true;
    }
    private boolean isEmptyRow(char[][] image, int row){
        for (int i = 0; i < image[0].length; i++){
            if (image[row][i] == '1'){
                return false;
            }
        }
        return true;
    }
}

另外這題不給(x,y),二分思路一樣。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章