您的位置:首页 > 其它

在01矩阵中找最大1矩形

2017-09-23 18:16 363 查看
题目:

给定一个01矩阵,求该矩阵内部的满足以下条件的最大的矩形的左上角所在的行和列,以及该矩形的长和宽。该矩形满足边上全为1,内部可0可1。(假定所有输入有且仅有一个矩形满足条件)

package Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

class Position {
public int x = 0;
public int y = 0;
public int w = 0;
public int h = 0;
public int a = 0;

public Position(int x, int y) {
this.x = x;
this.y = y;
}

public String toString() {
return "(" + x + ", " + y + ")" + "(" + w + ", " + h + ") " + a + "\n";
}
}

/**
* 思路:先优化矩阵,去掉无效点;找左上点;求每个左上点可以形成的最大矩形面积;在结果集中找出最大面积的位置信息
* clean() 去掉无效点
* travel() 遍历矩阵,找出左上点
* checkAll() 求每个左上点可以形成的最大矩形
* findMax() 在可以组成矩形的结果中找最大面积
* @author w18666
*
*/
public class Solution {

public static void main(String[] args) {
int[][] Mat = { {0, 0, 1, 1, 0, 0, 0, 0, 1},
{0, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 1, 1, 0, 1, 0, 1, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 0, 1},
{0, 0, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 1, 0, 1, 0, 0},
};
Mat = clean(Mat);
//printArr(Mat);
List<Position> list = checkAll(travel(Mat), Mat);
//System.out.println(list);
Position p = findMax(list);
System.out.println((p.x + 1) + " " + (p.y + 1) + " " + (p.h + 1) + " " + (p.w + 1));
}

public static int[][] clean(int[][] Mat) {
int m = Mat.length;	//m行
int n = Mat[0].length;	//n列

for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (0 != Mat[i][j]) {
int s = 0;
if (i > 0 && Mat[i - 1][j] == 1) s += 1;	//上
if (i < m - 1 && Mat[i + 1][j] == 1) s += 1;	//下
if (j > 0 && Mat[i][j - 1] ==1 ) s += 1;	//左
if (j < n - 1 && Mat[i][j + 1] == 1) s += 1;	//右
if (s <= 1) Mat[i][j] = 0;
}
}
}
return Mat;
}

public static List<Position> travel(int[][] Mat) {
int m = Mat.length;	//m行
int n = Mat[0].length;	//n列

List<Position> list = new ArrayList<Position>();
for (int i = 0; i < m - 1; i++) {
for (int j = 0; j < n - 1; j++) {
if (0 != Mat[i][j] && 1 == Mat[i + 1][j] && 1 == Mat[i][j + 1]) {	//
Position p = new Position(i, j);
int x = i, y = j, w = 0, h = 0;
while (x < m - 1 && Mat[++x][j] == 1) ++h;
while (y < n - 1 && Mat[i][++y] == 1) ++w;
p.h = h;
p.w = w;
list.add(p);
}
}
}
return list;
}

public static List<Position> checkAll(List<Position> list, int[][] Mat) {

Iterator<Position> it = list.iterator();
while (it.hasNext()) {
Position p = it.next();

int hh = p.h, ww = p.w;
for (int i = 0; i < p.h; i++) {
p.h -= i;
for (int j = 0; j < p.w ; j++) {
p.w -= j;
if (check(p, Mat) && p.h * p.w > p.a) {
p.a = p.h * p.w;
hh = p.h;
ww = p.w;
}
}
}
p.h = hh;
p.w = ww;
}
return list;
}

public static boolean check(Position p, int[][] Mat) {
int m = Mat.length;	//m行
int n = Mat[0].length;	//n列
int i = p.x, j = p.y;
while (i < m && Mat[i][p.y + p.w] == 1) {//右边
i++;
}
while (j < n && Mat[p.x + p.h][j] == 1) {//下边
j++;
}
if (--j == p.h || --i == p.w) {
return false;
}
return true;
}

public static void printArr(int[][] Mat) {
int m = Mat.length;	//m行
int n = Mat[0].length;	//n列
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print(Mat[i][j] + "  ");
}
System.out.println("\n");
}
}

public static Position findMax(List<Position> list) {
if (list.isEmpty()) return null;
Position max = list.get(0);
if (list.size() == 1) return max;

Iterator<Position> it = list.iterator();
while (it.hasNext()) {
Position p = it.next();
if (p.a > max.a) {
max = p;
}
}
return max;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: