思路:
1 直接暴力法,每到一个新的节点就判断以它为左上角是否有正方形,在判断的过程中需要考虑多个条件,及时break减少时间消耗
理论上该方法的时间复杂度为O(n*m)*min(n,m) (因为正方形长度最大也就原始网格长宽中最小的一个) ,空间复杂度为O(1)
2 考虑到主要的耗时在于判断当前节点是否能构成正方形,可以考虑记录每个节点上下左右为1的边的状态,这样后续节点的判断只需要简单的加减即可。 思路进一步可以简化为只需要记录每个节点左边连续1的个数和上边连续1的个数即可
代码:
class Solution {
public:
int largest1BorderedSquare(vector<vector<int>>& grid) {
//考虑到主要的耗时在于判断当前节点是否能构成正方形,可以考虑记录每个节点上下左右为1的边的状态,这样后续节点的判断只需要简单的加减即/可。 思路进一步可以简化为只需要记录每个节点左边连续1的个数和上边连续1的个数即可
vector<vector<vector<int> > > dp(grid.size()+1,vector<vector<int> >(grid[0].size()+1,vector<int>(2,0)));
//第一行的上面为0,第一列的左边为0
int len=0,maxlen=0;
for(int i=1;i<dp.size();++i)
for(int j=1;j<dp[0].size();++j)
{
if(grid[i-1][j-1]==1)
{
dp[i][j][0]=dp[i][j-1][0]+1; //上面及自身的连续1的个数
dp[i][j][1]=dp[i-1][j][1]+1; //左边及自身的连续1的个数
len=min( dp[i][j][0], dp[i][j][1]);//可能的最大正方形边长是两者中更小的一个
while(len>=1)
{
if(dp[i][j-len+1][1]>=len&&dp[i-len+1][j][0]>=len)//当正方形左下角的点的上方1的个数和正方形右上角的点的左边的1的个数///符合要求时
{
if(len>maxlen) maxlen=len;
break;
}
len--;
}
}
}
return maxlen*maxlen;
}
};
后续延伸:将题目改成寻找面积最大的矩阵而不是正方形,那么代码如何修改呢?
还是可以按照之前的来,但是代码中while循环处需要修改为对长宽都进行判断