程序员面试金典 17.23

本文介绍了一种在由0和1组成的矩阵中寻找最大零边界方阵的算法。通过预计算每个位置向右和向下连续0的数量,将时间复杂度优化至O(n^3)。文章详细解释了算法原理及其实现过程。

Max Square Matrix:矩阵中的元素只有01,找出一个最大的方阵,满足方阵四条边上的元素全为0

肯定要枚举所有可能的矩阵,因此O(n ^ 3)的复杂度是起点,然后就是在最内层循环中去判断是否可能是方阵。因为会用到每一个点向右以及向下的连续0的长度,所以整体的复杂度就为O(n ^ 4)。但是可以通过O(n ^ 2)的预计算,将每个位置上向右和向左连续0的数量计算出来,这样复杂度就还是O(n ^ 3)

class Solution {
private:
    vector<vector<int>> RightZero, DownZero;
    void precompute(const vector<vector<int>> &matrix)
    {
        RightZero.assign(matrix.size(), vector<int>(matrix[0].size(), 0));
        DownZero.assign(matrix.size(), vector<int>(matrix[0].size(), 0));
        RightZero.back().back() = DownZero.back().back() = matrix.back().back() == 0 ? 1 : 0;
        for(size_t c = matrix.back().size() - 1; c > 0; c--)
        {
            RightZero.back()[c - 1] = matrix.back()[c - 1] == 0 ? RightZero.back()[c] + 1 : 0;
            DownZero.back()[c - 1] = matrix.back()[c - 1] == 0 ? 1 : 0;
        }
        for(size_t r = matrix.size() - 1; r > 0; r--)
        {
            RightZero[r - 1].back() = matrix[r - 1].back() == 0 ? 1 : 0;
            DownZero[r - 1].back() = matrix[r - 1].back() == 0 ? DownZero[r].back() + 1 : 0;
        }
        for(size_t r = matrix.size() - 1; r > 0; r--)
        {
            for(size_t c = matrix.size() - 1; c > 0; c--)
            {
                RightZero[r - 1][c - 1] = matrix[r - 1][c - 1] == 0 ? RightZero[r - 1][c] + 1 : 0;
                DownZero[r - 1][c - 1] = matrix[r - 1][c - 1] == 0 ? DownZero[r][c - 1] + 1 : 0;
            }
        }
    }
    vector<int> compute(const vector<vector<int>>& matrix)
    {
        for(size_t size = matrix.size(); size > 0; size--)
        {
            for(size_t r = 0; r + size <= matrix.size(); r++)
            {
                for(size_t c = 0; c + size <= matrix.size(); c++)
                {
                    pair<int, int> TopLeft(RightZero[r][c], DownZero[r][c]);
                    pair<int, int> TopRight(RightZero[r][c + size - 1], DownZero[r][c + size - 1]);
                    pair<int, int> BottomLeft(RightZero[r + size - 1][c], DownZero[r + size - 1][c]);
                    if(TopLeft.first >= size &&
                        TopLeft.second >= size &&
                        TopRight.second >= size &&
                        BottomLeft.first >= size){
                            return { static_cast<int>(r), static_cast<int>(c), static_cast<int>(size) };
                        }
                }
            }
        }
        return {};
    }
public:
    vector<int> findSquare(vector<vector<int>>& matrix) {
        precompute(matrix);
        return compute(matrix);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值