最大正方形(力扣)暴力 + 动态规划 JAVA

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

示例 1:

在这里插入图片描述

输入:matrix =
[[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]
输出:4

示例 2:

在这里插入图片描述

输入:matrix = [[“0”,“1”],[“1”,“0”]]
输出:1

示例 3:

输入:matrix = [[“0”]]
输出:0

提示:

m == matrix.length
n == matrix[i].length
1 <= m, n <= 300
matrix[i][j] 为 ‘0’ 或 ‘1’

解题思路:

暴力破解:

1.注意题目中求的是最大正方形,不包括长方形

在这里插入图片描述
2.判断可能的最大正方形的边长

int mblen = Math.min(x - i, y - j);

3.判断正方形对角线是否为‘1’

for(int k = 1; k < mblen; k ++) {
                       
        			   if(matrix[i + k][j + k] == '0') { 
        				   check = false;
        				   break;//检查对角线
        			   }

4.若而对角线为‘1’判断正方形对角线两边是否都为‘1’

     			   for(int m = 0; m < k; m ++) {//检查正方形对角线两边是否都为1
        				  if(matrix[i + k][j + m] == '0' || matrix[i + m][j + k] == '0') { 
        					  check = false;
        					  break;
        				  }
        			   }

完整暴力破解代码:

class Solution {
    public int maximalSquare(char[][] matrix) {
           if(matrix.length == 0 || matrix[0].length == 0) return 0;
           int maxslen = 0;
           int x = matrix.length;
           int y = matrix[0].length;
           for(int i = 0; i < x; i ++)
        	   for(int j = 0; j < y; j ++) {
        		 if(matrix[i][j] == '1') {//在第一个为1的前提下才能检查后面的
                   maxslen = Math.max(1, maxslen);
        		   int mblen = Math.min(x - i, y - j);
        		   boolean check = true; 
        		   for(int k = 1; k < mblen; k ++) {
                       
        			   if(matrix[i + k][j + k] == '0') { 
        				   check = false;
        				   break;//检查对角线
        			   }
        			   
        			   for(int m = 0; m < k; m ++) {//检查正方形对角线两边是否都为1
        				  if(matrix[i + k][j + m] == '0' || matrix[i + m][j + k] == '0') { 
        					  check = false;
        					  break;
        				  }
        			   }
        			   
        			   if(check) maxslen = Math.max(maxslen, k + 1);//都为1更新//or check == true;
        			   else break;//否者没必要继续更新下去了
        		   }
        	   }
        	  }
           return maxslen * maxslen;
    }
}

在这里插入图片描述


动态规划:

1.设立dp[i][j] 即以(i, j)点为正方形右下角的最大边长

2.边界问题当 i=0 || j =0时dp[i][j] 最大为1

3.dp[i][j]由其左边、右边、左上角的最小值决定

4.
在这里插入图片描述
5.
在这里插入图片描述
6.

在这里插入图片描述

动态规划代码:

class Solution {
    public int maximalSquare(char[][] matrix) {
           int x = matrix.length;
           int y = matrix[0].length;
           if(x == 0 || y == 0) return 0;
           int dp[][] = new int[x][y];
           int maxlen = 0;
           for(int i = 0;i < x; i ++)
        	   for(int j = 0; j < y; j ++) {
        		   if(matrix[i][j] == '1') {
        			   if(i == 0 || j == 0) dp[i][j] = 1;
        			   else dp[i][j] = Math.min(dp[i - 1][j], Math.min(dp[i - 1][j - 1], dp[i][j - 1])) + 1;
        		   }
        		   maxlen = Math.max(maxlen, dp[i][j]);
        	   }
           return maxlen * maxlen;
    }
}

在这里插入图片描述

动态规划优点在于用更多空间储存前面的计算的成果,使得在计算新的点时可以借助前面的成果迭代过来,类似于将四阶楼梯,分成一节一节去爬,前面一节会对后面一节产生辅助作用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值