lintcode刷题——最大正方形

原题如下:

最大正方形 

在一个二维01矩阵中找到全为1的最大正方形

样例
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0

返回 4

做题思路:

1、看题应该知道要用动态规划来做,主要的就是求出状态方程。再设定一个大小和原矩阵相同的矩阵,用来存放到当前位置为止最大的正方形;

2、以第i,j个元素为右下角的正方形只和i-1,j  i,j-1  i-1,j-1这三个位置的元素有关,只需要对这三个元素判断其是否为1即可,当然前提是第i,j个元素不为0,如果为0了直接取那三个元素的最大值。

具体的c++代码如下:

class Solution {
public:
    /*
     * @param matrix: a matrix of 0 and 1
     * @return: an integer
     */
    int maxSquare(vector>& matrix) {
        // write your code here
        int m=matrix.size();
        if(m==0)
        {
            return 0;
        }
        int n=matrix[0].size();
        if(n==0)
        {
            return 0;
        }
        vector> square(m,vector(n,0));
        int i,j;
        int lenth=0;
        for(i=0;i         {
            square[i][0]=matrix[i][0];
            lenth=max(lenth,square[i][0]);
        }
        for(j=0;j         {
            square[0][j]=matrix[0][j];
            lenth=max(lenth,square[0][j]);
        }
        
        for(i=1;i         {
            for(j=1;j             {
                if(matrix[i][j]==1)
                {
                    square[i][j]=min(square[i-1][j],min(square[i][j-1],square[i-1][j-1]))+1;
                }
                lenth=max(square[i][j],lenth);
              
            }
            
        }
        return lenth*lenth;
    }
};


这道题其实和背包算法有一些类似,分析题目可知,当前的最大正方形的值其实只和上一行的数据相关,所以只需要用两行数据即可,于是对上面的代码做出一些修改:

用两个vector v1和v2存储当前的两行数据。

int m = matrix.size();
if (m == 0)
{
return 0;
}
int n = matrix[0].size();
if (n == 0)
{
return 0;
}
vector v1(n, 0);
vector v2(n, 0);
int i, j;
int lenth = 0;
for (j = 0; j{
v1[j] = matrix[0][j];
lenth = max(lenth, v1[j]);
}
for (i = 1; i{
v2[0] = matrix[i][0];
for (j = 1; j{
if (matrix[i][j] == 1)
{
v2[j] = min(v2[j - 1], min(v1[j], v1[j - 1])) + 1;
lenth = max(v2[j], lenth);
}


}
for (j = 0; j < n; j++)
{
v1[j] = v2[j];
v2[j] = 0;
}




}




return lenth*lenth;

你可能感兴趣的:(lintcode刷题)