描述

这是一篇面对初级coder的题解。
知识点:动态规划 二维vector使用
难度:二星


题解

给定一个由'0'和'1'组成的2维矩阵,返回该矩阵中最大的由'1'组成的正方形的面积
分析:
与NC109相比,由于寻找的正方形较为规整 所以可以动态规划


方法一:暴力求解

遍历数组 对于每一个可能是1的点 循环扩大正方形面积
扩大面积时可按如下方法遍历 保证只遍历一遍:

class Solution {
public:
    int findsquare(vector<vector<char> >& matrix,int i,int j,int l,int w)
    {
        int ans=1;//最小1
        //循环加L型 扩大正方形
        while(1)
        {
            for(int side=0;side<ans+1;side++)//左侧竖列 由上到下
            {
                if(l<=i+ans||w<=j+side||'0'==matrix[i+ans][j+side])
                    return ans;
            }
            for(int side=0;side<ans+1;side++)//下侧横行 由左到右
            {
                if(l<=i+side||w<=j+ans||'0'==matrix[i+side][j+ans])
                    return ans;
            }
            ans++;
        }
        
        return ans;
    }
    int solve(vector<vector<char> >& matrix) {
        int ans=0;//返回答案
        int l=matrix.size() ,w=matrix[0].size();//矩阵长宽
        for(int i=0;i<l;i++)//双重遍历
        {
            for(int j=0;j<w;j++)
            {
                if('1'==matrix[i][j])//=1 是正方形
                {
                int maxsquare=findsquare(matrix,i,j,l,w);//迭代判断最大边长
                if(ans<maxsquare)
                    ans=maxsquare;//当前值大于最大值 记录最大边长
                }
            }
        }
        return ans*ans;//返回面积
    }
};

时间复杂度:其中 是矩阵的行数和列数。需要遍历整个矩阵寻找每个 1,遍历矩阵的时间复杂度是 对于每个可能的正方形,最坏情况下,其边长不超过 和  中的最小值,需要遍历每个元素判断,故最坏情况时间复杂度,最好情况即使最大正方形边长为1,时间复杂度
空间复杂度O(1):没有额外使用的空间

运行时间3ms 占用内存396KB


方法二:动态规划

从[1,1]开始遍历进行动态规划

递归公式
matrix[i][j] = min(matrix[i - 1][j], min(matrix[i - 1][j - 1], matrix[i][j - 1])) + 1;
注:这里为了节约内存,直接在原数组上输出,最开始+1相当于是在char上+1 故要最后转化为int
class Solution {
public:
    int solve(vector<vector<char> >& matrix) {
        int ans=0;//返回答案
        int l=matrix.size() ,w=matrix[0].size();//矩阵长宽
        for (int i=1;i<l;i++) 
        {
            for (int j=1;j<=w;j++) 
            {
                if(matrix[i][j]=='1')//符合递归条件
                {
                    //递推公式
                    matrix[i][j] = min(matrix[i - 1][j], min(matrix[i - 1][j - 1], matrix[i][j - 1])) + 1;
                    //记录最大的边长
                    ans = max(ans, (int)matrix[i][j]);
                }
            }
        }
        return (ans-'0')*(ans-'0');//转化为10进制输出
    }
};
运行时间3ms 占用内存384KB
时间复杂度:其中  和是矩阵的行数和列数。需要遍历整个矩阵寻找每个 1
空间复杂度O(1):直接在原数组上进行操作,没有额外使用的空间

有递推性质的问题可以考虑动态规划
原数组不要的时候可以直接在原数组上输出