302. Smallest Rectangle Enclosing Black Pixels

零矩阵中由一坨以(x, y)为中心相连的1,让找出这坨1的四边边界。因为是相连的,拿上边界来说,从[0, x]中某行开始往后都出现了1,那行就是上边界。因此二分法找第一个1出现的行,对每个候选mid行,遍历列检查是否由1存在。其余边界同理,上下边界找完后有1存在的行范围已固定,可以用此帮助缩小在找左右边界中行要检查的范围。

题目和答案参考自

class Solution {
public:
    int minArea(vector<vector<char>>& image, int x, int y) {
        const int M = image.size(), N = image[0].size();
        // h: 遍历列还是行; i, j: 二分范围;low high: 检查有无1的范围;delta: 没查到1后往哪边动
        const auto bs = [&](bool h, int i, int j, int low, int high, int delta) {
            while (i < j) {
                int k = low, mid = i + (j - i) / 2;
                // 沿着一直搜索直到找到1
                while (k < high && (h ? image[mid][k] : image[k][mid]) == '0') ++k;
                // 是否遍历到了边界,到了意味着此行/列没有1
                if (k == high) i = mid + delta;
                else j = mid;
            }
            return i;
        };
        int up = bs(true, 0, x, 0, N, true, 1);
        int down = bs(true, x + 1, M, 0, N, -1);
        int left = bs(false, 0, y, up, down, 1);
        int right = bs(false, y + 1, N, up, down, -1);
    }
};

Last updated