[CareerCup] 18.11 Maximum Subsquare 最大子方形

简介:

18.11 Imagine you have a square matrix, where each cell (pixel) is either black or white. Design an algorithm to find the maximum subsquare such that all four borders are filled with black pixels.

LeetCode上的原题,请参见我之前的解法Maximal Square。书上给了两种解法,但是比较长:

解法一:

class Subsquare {
public:
    int row, col, size;
    Subsquare(int r, int c, int sz): row(r), col(c), size(sz) {}
    void print() {
        cout << "(" << row << ", " << col << ", " << size << ")" << endl;
    }
};

bool is_square(vector<vector<int>> &matrix, int row, int col, int size) {
    for (int j = 0; j < size; ++j) {
        if (matrix[row][col + j] == 1) return false;
        if (matrix[row + size - 1][col + j] == 1) return false;
    }
    for (int i = 1; i < size - 1; ++i) {
        if (matrix[row + i][col] == 1) return false;
        if (matrix[row + i][col + size - 1] == 1) return false;
    }
    return true;
}

Subsquare* find_square_with_size(vector<vector<int>> &matrix, int squareSize) {
    int cnt = matrix.size() - squareSize + 1;
    for (int row = 0; row < cnt; ++row) {
        for (int col = 0; col < cnt; ++col) {
            if (is_square(matrix, row, col, squareSize)) {
                return new Subsquare(row, col, squareSize);
            }
        }
    }
    return NULL;
}

Subsquare* find_square(vector<vector<int>> &matrix) {
    for (int i = matrix.size(); i >= 1; --i) {
        Subsquare *square = find_square_with_size(matrix, i);
        if (square) return square;
    }
    return NULL;
}

解法二:

class Subsquare {
public:
    int row, col, size;
    Subsquare(int r, int c, int sz): row(r), col(c), size(sz) {}
    void print() {
        cout << "(" << row << ", " << col << ", " << size << ")" << endl;
    }
};

class SquareCell {
public:
    int zerosRight = 0, zerosBelow = 0;
    SquareCell(int right, int below): zerosRight(right), zerosBelow(below){}
    void setZerosRight(int right) {
        zerosRight = right;
    }
    void setZerosBelow(int below) {
        zerosBelow = below;
    }
};

bool is_square(vector<vector<SquareCell*>> &matrix, int row, int col, int size) {
    SquareCell *topLeft = matrix[row][col];
    SquareCell *topRight = matrix[row][col + size - 1];
    SquareCell *bottomRight = matrix[row + size - 1][col];
    if (topLeft->zerosRight < size) return false;
    if (topLeft->zerosBelow < size) return false;
    if (topRight->zerosBelow < size) return false;
    if (bottomRight->zerosRight < size) return false;
    return true;
}

vector<vector<SquareCell*>> process_square(vector<vector<int>> &matrix) {
    vector<vector<SquareCell*>> res(matrix.size(), vector<SquareCell*>(matrix.size()));
    for (int r = matrix.size() - 1; r >= 0; --r) {
        for (int c = matrix.size() - 1; c >= 0; --c) {
            int rightZeros = 0, belowZeros = 0;
            if (matrix[r][c] == 0) {
                ++rightZeros;
                ++belowZeros;
                if (c + 1 < matrix.size()) {
                    SquareCell *pre = res[r][c + 1];
                    rightZeros += pre->zerosRight;
                }
                if (r + 1 < matrix.size()) {
                    SquareCell *pre = res[r + 1][c];
                    belowZeros += pre->zerosBelow;
                }
            }
            res[r][c] = new SquareCell(rightZeros, belowZeros);
        }
    }
    return res;
}

Subsquare* find_square_with_size(vector<vector<SquareCell*>> &processed, int square_size) {
    int cnt = processed.size() - square_size + 1;
    for (int row = 0; row < cnt; ++row) {
        for (int col = 0; col < cnt; ++col) {
            if (is_square(processed, row, col, square_size)) {
                return new Subsquare(row, col, square_size);
            }
        }
    }
    return NULL;
}

Subsquare* find_square(vector<vector<int>> &matrix) {
    vector<vector<SquareCell*>> processed = process_square(matrix);
    // cout << "here" << endl;
    for (int i = matrix.size(); i >= 1; --i) {
        Subsquare *square = find_square_with_size(processed, i);
        if (square) return square;
    }
    return NULL;
}

本文转自博客园Grandyang的博客,原文链接: 最大子方形[CareerCup] 18.11 Maximum Subsquare,如需转载请自行联系原博主。

相关文章
|
7月前
|
人工智能 算法
A. Average Height(找相邻的数除2产生整数更多的排列)(codeforces715)
A. Average Height(找相邻的数除2产生整数更多的排列)(codeforces715)
15 0
2021杭电多校第八场 HDU7063-Square Card(求两圆相交面积)
2021杭电多校第八场 HDU7063-Square Card(求两圆相交面积)
56 0
2021杭电多校第八场 HDU7063-Square Card(求两圆相交面积)
POJ1269 Intersecting Lines(两直线关系)
POJ1269 Intersecting Lines(两直线关系)
43 0
|
vr&ar
3DMax教程 教你在3DMax中怎么渲染黑色的描边
渲染黑色的描边有三种方法: 1、VR材质的漫反射贴图给一个VR边纹理材质,颜色给黑色,添加一个特效。 2、还有一种就是原地复制一个模型,给个Lattice修改器,然后给个黑色材质 3、复制一个模型给个Lattice修改器变成线型,给个黑色材质
380 0
3DMax教程 教你在3DMax中怎么渲染黑色的描边