最大正方形

在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。

示例:

输入: 

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0

输出: 4

1、暴力法

计算二维矩阵里,每一个 正方形的面积,判断是否只包含1,如果是算出面积,并取面积最大者的值。

	public int solve(char[][] matrix, int startRow, int startCol)
	{
		int rowLen = matrix.length;
		int colLen = matrix[0].length;
		int len = rowLen < colLen ? rowLen : colLen; // 取较小的边长
		int maxArea = 0;  // 最大面积
		int currArea = 0; //当前的面积
		for (int i=0; i<len; i++) // 边长范围
		{
			if (!isLegal(matrix, startRow, startCol, i))
			{
				startCol++;
				// 改变正方形起始顶点的位置
				if (startCol == colLen) // 到达最后一列
				{
					startRow++;
					if (startRow == rowLen) // 到达最后一行
						break;
					startCol = 0;
				}
				
				i = -1;
			}
			else
			{
				currArea = (i+1)*(i+1);
				maxArea = maxArea > currArea ? maxArea : currArea;
			}
		}
		return maxArea;
	}
	
	// 判断以startRow,startCol为起点的正方形是否只包含1
	boolean isLegal(char[][] matrix, int startRow, int startCol, int len)
	{
		boolean rowEnd = startRow + len >= matrix.length ? false : true;
		boolean colEnd = startCol + len >= matrix[0].length ? false : true;
		if (rowEnd==false || colEnd==false)
			return false;
		for (int i=startRow; i<=startRow+len; i++)
		{
			for (int j=startCol; j<=startCol+len; j++)
			{
				if (matrix[i][j] != '1')
					return false;
			}
		}
		return true;
	}
	
	
    public int maximalSquare(char[][] matrix) 
    {
    	if (matrix == null || matrix.length == 0)
    		return 0;
    	return solve(matrix, 0, 0);
    }

2、动态规划

状态转移方程: dp[i][j] = 1 + min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]);

    public int maximalSquare(char[][] matrix) 
    {
    	if (matrix == null || matrix.length == 0)
    		return 0;
    	int m = matrix.length; // 行数
    	int n = matrix[0].length; // 列数
    	int maxLen = 0;
    	
    	// dp[i][j]表示以第i行第j列为右下角所能构成的最大正方形边长
    	int[][] dp = new int[m+1][n+1];
    	
    	for (int i=1; i<=m; i++)
    	{
    		for (int j=1; j<=n; j++)
    		{
    			if (matrix[i-1][j-1] == '1')
    			{
    				dp[i][j] = 1 + Math.min(dp[i-1][j-1], Math.min(dp[i-1][j], dp[i][j-1]));
    				maxLen = Math.max(maxLen, dp[i][j]);
    			}
    		}
    	}
    	return maxLen * maxLen;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值