[算法]边界都是1的最大正方形大小

题目:

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

例如:

0     1     1     1     1

0     1     0     0     1

0     1     0     0     1

0     1     1     1     1

0     1     0     1     1

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

思路:

方法一:

1.矩阵中一共有N*N个位置。O(N2)

2.对每一个位置都可以成为边长为N~1的正方形左上角。比如,对于(0,0)位置,依次检查是否是边长为5的正方形的左上角,然后检查边长为4、3等。O(N)

3.如何检查一个位置是否可以成为边长为N的正方形的左上角?遍历这个边长为N的正方形边界看是否只由1组成,也就是走过四个边的长度(4N)。O(N)

总的时间复杂度:O(N2)*O(N)*O(N)=O(N4)

方法二:

时间复杂度为O(N3)

采用预处理方法。

1.预处理过程是根据matrix得到两个矩阵right和down,right[i][j]的值表示从位置(i,j)向右出发有多少个连续的1。down[i][j]的值表示从位置(i,j)向下出发有多少个连续的1。

2.right与down的计算。

  • 从矩阵的右下角(n-1,n-1)位置开始计算,如果matrix[n-1][n-1]=1,那么,right[n-1][n-1]=1,down[n-1][n-1]=1,否则都等于0。

  • 从右下角向上计算,即在matrix最后一列上计算,位置就表示为(i,n-1)。对right来说,最后一列的右边没有内容,所以,如果matrix[i][n-1]=1,             right[i][n-1]=1并且down[i][n-1]=down[i+1][n-1]+1,否则right[i][n-1]=0并且down[i][n-1]=0。
  • 从右下角向左计算,即在matrix最后一行上计算,位置就表示为(n-1,j)。对down来说,最后一行的下边没有内容,所以,如果matrix[n-1][j]=1,           down[n-1][j]=1并且right[n-1][j]=down[n-1][j+1]+1,否则right[n-1][j]=0并且down[n-1][j]=0。
  • 剩下的位置都是既有右,又有下,假设位置(i,j):
    • if matrix[i][j]=1, then right[i][j+1]=right[i][j]+1,down[i][j]=down[i+1][j]+1.

    • if matrix[i][j]=0,then right[i][j]=0,down[i][j]=0.
	public static void setBorderMap(int[][] m, int[][] right, int[][] down) {
		int r = m.length;
		int c = m[0].length;
		if (m[r - 1][c - 1] == 1) {
			right[r - 1][c - 1] = 1;
			down[r - 1][c - 1] = 1;
		}
		for (int i = r - 2; i != -1; i--) {
			if (m[i][c - 1] == 1) {
				right[i][c - 1] = 1;
				down[i][c - 1] = down[i + 1][c - 1] + 1;
			}
		}
		for (int i = c - 2; i != -1; i--) {
			if (m[r - 1][i] == 1) {
				right[r - 1][i] = right[r - 1][i + 1] + 1;
				down[r - 1][i] = 1;
			}
		}
		for (int i = r - 2; i != -1; i--) {
			for (int j = c - 2; j != -1; j--) {
				if (m[i][j] == 1) {
					right[i][j] = right[i][j + 1] + 1;
					down[i][j] = down[i + 1][j] + 1;
				}
			}
		}
	}

	public static int getMaxSize(int[][] m) {
		int[][] right = new int[m.length][m[0].length];
		int[][] down = new int[m.length][m[0].length];
		setBorderMap(m, right, down);
		for (int size = Math.min(m.length, m[0].length); size != 0; size--) {
			if (hasSizeOfBorder(size, right, down)) {
				return size;
			}
		}
		return 0;
	}

	public static boolean hasSizeOfBorder(int size, int[][] right, int[][] down) {
		for (int i = 0; i != right.length - size + 1; i++) {
			for (int j = 0; j != right[0].length - size + 1; 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 static int[][] generateRandom01Matrix(int rowSize, int colSize) {
		int[][] res = new int[rowSize][colSize];
		for (int i = 0; i != rowSize; i++) {
			for (int j = 0; j != colSize; j++) {
				res[i][j] = (int) (Math.random() * 2);
			}
		}
		return res;
	}

时间: 2024-09-29 11:25:27

[算法]边界都是1的最大正方形大小的相关文章

飞行游戏中的碰撞算法-边界框碰撞检测

参考源地址http://xxxxxfsadf.iteye.com/blog/540669 在飞行射击游戏中,我们的飞机大多都是三角形的,我们可以用三角形作近似的边界框.现在我们假设飞机是一个正三角形(或等要三角形,我想如果谁把飞机设计成左右不对称的怪物,那他的审美观一定有问题),我的飞机是正着的.向上飞的三角形,敌人的飞机是倒着的.向下飞的三角形,且飞机不会旋转(大部分游戏中都是这样的).我们可以这样定义飞机:中心点O(Xo,Yo),三个顶点P0(X0,Y0).P1(X1,Y1).P2(X2,Y

《机器学习实战》中的程序清单2-1 k近邻算法classify0都做了什么

def start(): group,labels = createDataSet() return classify0([3,3], group, labels, 4) def createDataSet(): group = array([[1,2],[2,3],[1,1],[4,5]]) #此处随意定义,表示一个已知的已分类的数据集 labels = ['A','A','B','B'] return group, labels def classify0(inX,dataSet,label

[Android算法] bitmap 将图片压缩到指定的大小

Bitmap压缩到指定大小: private void imageZoom() {//图片允许最大空间 单位:KBdouble maxSize =400.00;//将bitmap放至数组中,意在bitmap的大小(与实际读取的原文件要大)ByteArrayOutputStream baos = new ByteArrayOutputStream();bitMap.compress(Bitmap.CompressFormat.JPEG, 100, baos);byte[] b = baos.toB

程序员代码面试指南 IT名企算法与数据结构题目最优解 ,左程云著pdf高清版免费下载

下载地址:网盘下载 备用地址:网盘下载 内容简介  · · · · · ·这是一本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现.针对当前程序员面试缺乏权威题目汇总这一痛点,本书选取将近200道真实出现过的经典代码面试题,帮助广大程序员的面试准备做到万无一失.“刷”完本书后,你就是“题王”!__eol__本书采用题目+解答的方式组织内容,并把面试题类型相近或者解法相近的题目尽量放在一起,读者在学习本书时很容易看出面试题解法之间的联系,使知识的学习避免碎片化

数组和矩阵

目录 1.打印矩阵 转圈打印矩阵 将正方形矩阵顺时针转动90度 “之”字形打印矩阵 2.数组的遍历查找 找到无序数组中最小的k个数(topk) 一个数组,所有数都出现了两次(三次),只有一个数出现了一次,返回这个数, 一个1-n的数,少了一个,找出来 在数组中找到出现次数大于N/K的数[删除不同的数] 在行列都排好序的矩阵中找数 奇数下标都是奇数或偶数下标都是偶数[even.odd变量变量] 在数组中找到一个局部最小的位置 边界都是1的最大正方形大小[遍历+动态规划] 不包含本位置值的累乘数组[

JVM垃圾回收算法

1.堆的分代和区域 (年轻代)Young Generation(eden.s0.s1  space)    Minor GC (老年代)Old Generation (Tenured space)     Major GC|| Full GC (永久代)Permanent Generation (Permanent  space)[方法区(method area)]    Major GC 本地化的String从JDK 7开始就被移除了永久代(Permanent Generation ) JDK

[转] 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽

字符串模式匹配算法——BM.Horspool.Sunday.KMP.KR.AC算法一网打尽 转载自:http://dsqiu.iteye.com/blog/1700312 本文内容框架: §1 Boyer-Moore算法 §2 Horspool算法 §3 Sunday算法 §4 KMP算算法 §5 KR算法 §6 AC自动机 §7 小结 §1 Boyer-Moore(BM)算法 Boyer-Moore算法原理 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法,后缀匹配就是模式串从右到

推荐文章:机器学习:“一文读懂机器学习,大数据/自然语言处理/算法全有了

PS:文章主要转载自CSDN大神"黑夜路人"的文章:          http://blog.csdn.NET/heiyeshuwu/article/details/43483655      本文主要对机器学习进行科普,包括机器学习的定义.范围.方法,包括机器学习的研究领域:模式识别.计算机视觉.语音识别.自然语言处理.统计学习和数据挖掘.这是一篇非常好的文章,尤其感学原文作者~          http://www.thebigdata.cn/JieJueFangAn/1308

(floyd)佛洛伊德算法

Floyd–Warshall(简称Floyd算法)是一种著名的解决任意两点间的最短路径(All Paris Shortest Paths,APSP)的算法.从表面上粗看,Floyd算法是一个非常简单的三重循环,而且纯粹的Floyd算法的循环体内的语句也十分简洁.我认为,正是由于“Floyd算法是一种动态规划(Dynamic Programming)算法”的本质,才导致了Floyd算法如此精妙.因此,这里我将从Floyd算法的状态定义.动态转移方程以及滚动数组等重要方面,来简单剖析一下图论中这一重