最大0,1子矩阵

首先描述一下问题
[code]
/**
*
* 时间限制(普通/Java):6000MS/20000MS 运行内存限制:65536KByte
* 总提交:131 测试通过:32
* 描述
* 在一个0,1方阵中找出其中最大的全0子矩阵,所谓最大是指O的个数最多
* 输入
* 单组数据第一行为整数N,其中1<=N<=2000,为方阵的大小,紧接着N行每行均有N个0或1,相邻两数间严格用一个空格隔开
* 输出
* 输出仅一行包含一个整数表示要求的最大的全零子矩阵中零的个数
* 样例输入
* 5
* 0 1 0 1 0
* 0 0 0 0 0
* 0 0 0 0 1
* 1 0 0 0 0
* 0 1 0 0 0
* 样例输出
* 9
*/
[/code]
我的做法是遍历每个点,根据每个点横向和纵向的构造全0矩阵,选取最大的全0矩阵输出
正确性应该是没问题的,不过时间复杂度
遍历的复杂度是o(n^2)然后每个点构造矩形复杂度也是o(n^2)
最大时间复杂度就为n^4
因此求优化 :arrow:
[code]
package graph;
/**
*
* 时间限制(普通/Java):6000MS/20000MS 运行内存限制:65536KByte
* 总提交:131 测试通过:32
* 描述
* 在一个0,1方阵中找出其中最大的全0子矩阵,所谓最大是指O的个数最多
* 输入
* 单组数据第一行为整数N,其中1<=N<=2000,为方阵的大小,紧接着N行每行均有N个0或1,相邻两数间严格用一个空格隔开
* 输出
* 输出仅一行包含一个整数表示要求的最大的全零子矩阵中零的个数
* 样例输入
* 5
* 0 1 0 1 0
* 0 0 0 0 0
* 0 0 0 0 1
* 1 0 0 0 0
* 0 1 0 0 0
* 样例输出
* 9
*
* @author Leon.Chen
*
*/
public class AllZeroMatrix {
/**
* 输入矩阵
*/
public int[][] matrix;
/**
* 矩阵最大行
*/
public int maxRow;
/**
* 矩阵最大列
*/
public int maxColumn;
/**
* 被乘数
*/
public int multiplicand;
/**
* 最大全零矩阵
*/
public int totalCount;

/**
* 每个点向下,向右扩张矩形,取最大的矩形
*
* @param row
* @param column
*/
public void spread(int row, int column) {
int rowStart = row;
int rowEnd = row;
while (rowEnd < maxRow) {
if (matrix[rowEnd][column] == 0) {
rowEnd++;
} else {
break;
}
}
this.multiplicand = 0;
spreadMatrixRight(rowStart, rowEnd, column);
int count = (rowEnd - rowStart) * multiplicand;
if (totalCount < count) {
totalCount = count;
}
int columnStart = column;
int columnEnd = column;
while (columnEnd < maxColumn) {
if (matrix[row][columnEnd] == 0) {
columnEnd++;
} else {
break;
}
}
this.multiplicand = 0;
spreadMatrixbelow(columnStart, columnEnd, row);
count = (columnEnd - columnStart) * multiplicand;
if (totalCount < count) {
totalCount = count;
}
}

/**
* 矩阵的向右扩张
*
* @param start
* @param end
* @param column
*/

public void spreadMatrixRight(int start, int end, int column) {
boolean flg = true;
for (int i = start; i < end; i++) {
if (matrix[i][column] == 1) {
flg = false;
break;
}
}
if (flg) {
multiplicand++;
int nextColumn = column;
nextColumn++;
if (nextColumn < maxColumn) {
spreadMatrixRight(start, end, nextColumn);
}
}
}

/**
* 矩阵的向下扩张
*
* @param start
* @param end
* @param row
*/
public void spreadMatrixbelow(int start, int end, int row) {
boolean flg = true;
for (int i = start; i < end; i++) {
if (matrix[row][i] == 1) {
flg = false;
break;
}
}
if (flg) {
multiplicand++;
int nextRow = row;
nextRow++;
if (nextRow < maxRow) {
spreadMatrixbelow(start, end, nextRow);
}
}
}

/**
* 得到最大全零矩阵的大小
*
* @param printMatrix
*/
public void getAllZeroMatrix(int[][] printMatrix) {
matrix = printMatrix;
maxRow = matrix.length;
maxColumn = matrix[0].length;
for (int i = 0; i < maxRow; i++) {
for (int j = 0; j < maxColumn; j++) {
int count = (maxRow - i) * (maxColumn - j);
if (count <= totalCount) {
continue;
}
if (matrix[i][j] != 1) {
spread(i, j);
}
}
}
System.out.println(totalCount);
}

public static void main(String[] args) {
int[][] printMatrix = new int[][]{
{0,1,0,1,0},
{0,0,0,0,0},
{0,0,0,0,1},
{1,0,0,0,0},
{0,1,0,0,0},
};
long start = System.currentTimeMillis();
new AllZeroMatrix().getAllZeroMatrix(printMatrix);
long end = System.currentTimeMillis();
System.out.println((end-start)+"ms");
}
}

[/code]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值