边界都是1的最大正方形大小

题目:

给定一个M*N的矩阵,在这个矩阵中,只有0和1两种值,返回边框全是1的最大正方形的边长长度。

例如:

              [0, 1, 1, 1, 1], 

            [0, 0, 1, 0, 1],

            [0, 1, 1, 0, 1], 

            [0, 1, 1, 1, 1],  

            [0, 1, 0, 1, 1]

其中,边框全是1的最大正方形的大小为4。


解析:

1.正方形边长为0<=size<=Math.min(rows,cols);

2.边长为size时,左上角的坐标范围为 0<=i<=rows-size,0<=j<=cols-size;

3.使用预处理矩阵right和down,空间换时间,right[i][j]保存matrix[i][j]包括自己往右边有多少个1,同理down[i][j]。 

3.对每一个左上角的边长为size的矩形判断边上是否全为1,发现有满足的直接返回当前size。

 public int findLength(int[][] matrix)
   {
	   if(matrix == null||matrix.length == 0||matrix[0].length == 0)
		   return 0;
	   int rows=matrix.length;
	   int cols=matrix[0].length;
	   int[][] right=new int[rows][cols];
	   int[][] down=new int[rows][cols];
	   setRightAndDown(matrix,right,down);//预处理矩阵right和down;
	   for(int size=Math.min(rows, cols) ;  size > 0  ;  size--  )
	   {
		   if(has_size(size,right,down))
			   return size;
	   }
	   return 0;
   }
   //边长为size的边上为全1的矩形是否存在
   public boolean has_size(int size,int[][] right,int[][] down)
   {
	   int rows=right.length;
	   int cols=right[0].length;
	   for(int i=0;i<=rows-size;i++)
	   {
		   for(int j=0;j<=cols-size;j++)
		   {
			   if(right[i][j]>=size&&down[i][j]>=size&&right[i+size-1][j]>=size&&down[i][j+size-1]>=size)
				   return true;
		   }
	   }
	   return false;
   }
   
   //预处理例程
   public void  setRightAndDown(int[][] matrix,int[][] right,int[][] down)
   {
	   int rows=matrix.length;
	   int cols=matrix[0].length;
	   if(matrix[rows-1][cols-1] == 1)
	   {
		   right[rows-1][cols-1]=1;
		   down[rows-1][cols-1]=1;
	   }
	   //right col
	   for(int i=rows-2;i>=0;i--)
	   {
		   if(matrix[i][cols-1] == 1)
		   {
			   right[i][cols-1]=1;
			   down[i][cols-1]=down[i+1][cols-1]+1;
		   }
	   }
	   //end row
	   for(int j=cols-2;j>=0;j--)
	   {
		   if(matrix[rows-1][j] == 1)
		   {
			   down[rows-1][j]=1;
			   right[rows-1][j]=right[rows-1][j+1]+1;
		   }
	   }
	   //general
	   for(int i=rows-2;i>=0;i--)
	   {
		   for(int j=cols-2;j>=0;j--)
		   {
			   if(matrix[i][j] == 1)
			   {
				   right[i][j]=right[i][j+1]+1;
				   down[i][j]=down[i+1][j]+1;
			   }
		   }
	   }
   }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值