找出边界为1的最大子方阵
max(A,N)
int n=N;//这是n的四次方的复杂度,下面可以进行优化
while(n>0)
for(i=0 i<n;i++)
for(j=0 j<n;j++) //三层循环
//i,j是顶点
r = i;//定义个行移动量
c = j; //定义个列移动量
这里注意数组的越界,要判断
//上面一条边逻辑
while(c<j+n)
if A[r][c]==0 continue l3;
c++;
c-- //退出后c指针恢复到边界值
//右边的逻辑
while(r<i+n)
if A[r][c]==0 continue l3;
r++;
r--
//下边逻辑
while(c>=j)
if A[r][c]==0 continue l3;
c--;
c++;
while(r>=i)
if A[r][c]==0 continue l3;
r--;
r++;
return n;
n--;
另一种优化的解法可以初始化一个数组,将数组
的右方和下方是一的元素存入到数组中,返回一
个三维数组,对于数组中保存元素可以进行,例如对于一个
数组
int a = {1,1,0,0
1,1,1,1
1,1,1,0
1,1,0,1}
先从最后一行计算,计算出每个数组中放置的元素,然后进行返回
private static int[][][] help(int[][]a)
int N= A.length;
rec = new int [N][N][2];
int row = N-1;
//最后一行数组元素的生成
for(int j =N-1;j>=0;j--)//单循环
int value = A[row][j];
if(value==1)
if (j=n-1)
rec[row][j][0] = 1;//右边连续1的个数
else
rec[row][j][0] = rec[row][j+1][0]+1
rec[row][j][1] =1;
row--;
for(int i=row;i>=0;i--) //双循环
for(int j=n-1;j>=0;j--)
int value= a[i][j]
if (value==1)
if(j=n-1)
rec[i][j][0]=1
else
rec[i][j][0]=rec[i][j+1][0]+1;
rec[i][j][1] = rec[i+1][j][1]+1//向下连续1的个数
单加双循环是双循环
总结为啥优化:属于打表法,预处理的思想是用的动态规划的方法
对于n的3次方和n的四次方比较,如果n=100,则n的四次方就是10的
8次方就越界,所以需要优化。
例如:n*n*n*o(1)的优化和n*n*n*n*n的比较。
//对于check函数需要检测顶点
//左上角点往右数的1的数目要>=n if(rec[i][j][0]>=n)
左上交那个点往下数的1的数目要>=n if(rec[i][j][1]>=n)
右上角那个点往下数的1的数目要>=n if(rec[i][j+n-1][1]>=n)
左下角那个点往右数的1的数目要>=n if(rec[i+n-1][j][0]>=n)
如果都成功则返回true;
否则返回false
函数的所有伪代码如下:
max(A,N)
生成三维的数组
help(A)
int n =solve(int [][] A)
system out n
solve(A)////n的三次方
N=a.length;
int n=N;
while(n>0)
for (int i=0;i<n;i++)
if (i+n>N)break;
for(int j=0;j<n;j++)
if (j+n>N)break;
if (check(i,j,n))
return n;
n--;
return n;
本文探讨了一种优化的算法,用于寻找矩阵中边界为1的最大子方阵。通过动态规划策略,将原始O(n^4)的时间复杂度降低到O(n^3),并介绍了两种实现方法:一是逐行逐列检查边界,二是预先计算并存储连续1的计数。文章重点在于展示了优化思路和算法效率提升的重要性。

被折叠的 条评论
为什么被折叠?



